From 80f158b232f185ac9a0099f945c213f01c7761f6 Mon Sep 17 00:00:00 2001 From: Srinidhi Veeraraghavan Date: Fri, 19 Dec 2025 17:57:47 +0000 Subject: [PATCH 1/7] feat: add pulumi dependencies --- package.json | 6 + pnpm-lock.yaml | 1660 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 1657 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 864d77ac..04344046 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,12 @@ "@cdktf/provider-aws": "^21.22.1", "@cdktf/provider-azurerm": "^14.23.1", "@cdktf/provider-cloudflare": "^13.9.1", + "@pulumi/aws": "^7.14.0", + "@pulumi/azure-native": "^3.11.0", + "@pulumi/cloudflare": "^6.11.0", + "@pulumi/command": "^1.1.3", + "@pulumi/pulumi": "^3.213.0", + "@pulumi/std": "^2.2.0", "@types/lodash": "^4.17.21", "@types/node": "^25.0.3", "@types/uuid": "^11.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dd27ef01..56af54d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,24 @@ importers: '@cdktf/provider-cloudflare': specifier: ^13.9.1 version: 13.9.1(cdktf@0.21.0(constructs@10.4.4))(constructs@10.4.4) + '@pulumi/aws': + specifier: ^7.14.0 + version: 7.14.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + '@pulumi/azure-native': + specifier: ^3.11.0 + version: 3.11.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + '@pulumi/cloudflare': + specifier: ^6.11.0 + version: 6.11.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + '@pulumi/command': + specifier: ^1.1.3 + version: 1.1.3(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + '@pulumi/pulumi': + specifier: ^3.213.0 + version: 3.213.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + '@pulumi/std': + specifier: ^2.2.0 + version: 2.2.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) '@types/lodash': specifier: ^4.17.21 version: 4.17.21 @@ -110,7 +128,7 @@ importers: version: 2.7.3(prop-types@15.8.1)(react-dom@17.0.2(react@17.0.2))(react@17.0.2) codecov: specifier: ^3.8.3 - version: 3.8.3 + version: 3.8.3(encoding@0.1.13) commitizen: specifier: ^4.3.1 version: 4.3.1(@types/node@25.0.3)(typescript@5.9.3) @@ -920,6 +938,15 @@ packages: resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} + '@grpc/grpc-js@1.14.3': + resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.8.0': + resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==} + engines: {node: '>=6'} + hasBin: true + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -948,6 +975,9 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/string-locale-compare@1.1.0': + resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==} + '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} @@ -971,10 +1001,17 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jsdoc/salty@0.2.9': resolution: {integrity: sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==} engines: {node: '>=v12.0.0'} + '@logdna/tail-file@2.2.0': + resolution: {integrity: sha512-XGSsWDweP80Fks16lwkAUIr54ICyBs6PsI4mpfTLQaWgEJRtY9xEV+PeyDpJ+sJEGZxqINlpmAwe/6tS1pP8Ng==} + engines: {node: '>=10.3.0'} + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -990,6 +1027,64 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@npmcli/agent@2.2.2': + resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/arborist@7.5.4': + resolution: {integrity: sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/git@5.0.8': + resolution: {integrity: sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/installed-package-contents@2.1.0': + resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + '@npmcli/map-workspaces@3.0.6': + resolution: {integrity: sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/metavuln-calculator@7.1.1': + resolution: {integrity: sha512-Nkxf96V0lAx3HCpVda7Vw4P23RILgdi/5K1fmj2tZkWIYLpXAN8k2UVVOsW16TsS5F8Ws2I7Cm+PU1/rsVF47g==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/name-from-folder@2.0.0': + resolution: {integrity: sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/node-gyp@3.0.0': + resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/package-json@5.2.1': + resolution: {integrity: sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/promise-spawn@7.0.2': + resolution: {integrity: sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/query@3.1.0': + resolution: {integrity: sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/redact@2.0.1': + resolution: {integrity: sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/run-script@8.1.0': + resolution: {integrity: sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==} + engines: {node: ^16.14.0 || >=18.0.0} + '@octokit/auth-token@6.0.0': resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} engines: {node: '>= 20'} @@ -1056,6 +1151,82 @@ packages: '@octokit/types@16.0.0': resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + '@opentelemetry/api-logs@0.55.0': + resolution: {integrity: sha512-3cpa+qI45VHYcA5c0bHM6VHo9gicv3p5mlLHNG3rLyjQU8b7e0st1rWtrUn3JbZ3DwwCfhKop4eQ9UuYlC6Pkg==} + engines: {node: '>=14'} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/context-async-hooks@1.30.1': + resolution: {integrity: sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@1.30.1': + resolution: {integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/exporter-zipkin@1.30.1': + resolution: {integrity: sha512-6S2QIMJahIquvFaaxmcwpvQQRD/YFaMTNoIxrfPIPOeITN+a8lfEcPDxNxn8JDAaxkg+4EnXhz8upVDYenoQjA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/instrumentation-grpc@0.55.0': + resolution: {integrity: sha512-n2ZH4pRwOy0Vhag/3eKqiyDBwcpUnGgJI9iiIRX7vivE0FMncaLazWphNFezRRaM/LuKwq1TD8pVUvieP68mow==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.55.0': + resolution: {integrity: sha512-YDCMlaQRZkziLL3t6TONRgmmGxDx6MyQDXRD0dknkkgUZtOK5+8MWft1OXzmNu6XfBOdT12MKN5rz+jHUkafKQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/propagator-b3@1.30.1': + resolution: {integrity: sha512-oATwWWDIJzybAZ4pO76ATN5N6FFbOA1otibAVlS8v90B4S1wClnhRUk7K+2CHAwN1JKYuj4jh/lpCEG5BAqFuQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/propagator-jaeger@1.30.1': + resolution: {integrity: sha512-Pj/BfnYEKIOImirH76M4hDaBSx6HyZ2CXUqk+Kj02m6BB80c/yo4BdWkn/1gDFfU+YPY+bPR2U0DKBfdxCKwmg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/resources@1.30.1': + resolution: {integrity: sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/sdk-trace-base@1.30.1': + resolution: {integrity: sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/sdk-trace-node@1.30.1': + resolution: {integrity: sha512-cBjYOINt1JxXdpw1e5MlHmFRc5fgj4GW/86vsKFxJCJ8AL4PdVtYH41gWwl4qd4uQjqEL1oJVrXkSy5cnduAnQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.27.0': + resolution: {integrity: sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==} + engines: {node: '>=14'} + + '@opentelemetry/semantic-conventions@1.28.0': + resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==} + engines: {node: '>=14'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1072,6 +1243,63 @@ packages: resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} engines: {node: '>=12'} + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@pulumi/aws@7.14.0': + resolution: {integrity: sha512-Cpk4Xu9HD1DThVvWN28mlB8gGGIsdLnmKzzCPCsuX1+k7hGGlnS2qhUiS8Ve2bxvS7W6VYJ4x/+BXKv9hbXPtw==} + + '@pulumi/azure-native@3.11.0': + resolution: {integrity: sha512-ZPykUN3uj8aGoJc/Lr8cYuQMy+RzgcBUzEhNrMG03E1t/OURqkg6aK3IkIO+/rqJQDaW0SXRxhncoVESoG+SxA==} + + '@pulumi/cloudflare@6.11.0': + resolution: {integrity: sha512-KrKmoi7/L9Q8z2yr8PzNfcTo8Irm//NNJ5s4khQD9+W495Wd2k5fR1bOOEQN15iFsBALyjBbeDf+6+RdZKSd6A==} + + '@pulumi/command@1.1.3': + resolution: {integrity: sha512-eBzGE/BQlxMNcxrrA62N4cLaHdL0xDSRACXxB0Hjc4rJG60vhpDVO130xxb4x3cZ7HT1kvjS4KuuoH8R5JRbIQ==} + + '@pulumi/pulumi@3.213.0': + resolution: {integrity: sha512-qTAOJXQYjMse2oAwht4iuYA4TiSgUgDfGmlySf2xa4n34+eF1/ytCbF3UJdfOx9+yDD5mYBAi37t0OY/VyVzyQ==} + engines: {node: '>=20'} + peerDependencies: + ts-node: '>= 7.0.1 < 12' + typescript: '>= 3.8.3 < 6' + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + + '@pulumi/std@2.2.0': + resolution: {integrity: sha512-CtqnB+/UbSBCHXxlX5MoGxQChNdVFHx90xYckJmm4ZW8nf1qMWW2ioLZ0ZuXGMN9hdf84v+Vd5WkGmbdT/aXjQ==} + '@rollup/rollup-android-arm-eabi@4.53.5': resolution: {integrity: sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==} cpu: [arm] @@ -1232,6 +1460,30 @@ packages: peerDependencies: semantic-release: '>=20.1.0' + '@sigstore/bundle@2.3.2': + resolution: {integrity: sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/core@1.1.0': + resolution: {integrity: sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/protobuf-specs@0.3.3': + resolution: {integrity: sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==} + engines: {node: ^18.17.0 || >=20.5.0} + + '@sigstore/sign@2.3.2': + resolution: {integrity: sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/tuf@2.3.4': + resolution: {integrity: sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@sigstore/verify@1.2.1': + resolution: {integrity: sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==} + engines: {node: ^16.14.0 || >=18.0.0} + '@sindresorhus/base62@1.0.0': resolution: {integrity: sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==} engines: {node: '>=18'} @@ -1416,6 +1668,10 @@ packages: resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} engines: {node: '>=18.0.0'} + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + '@tootallnate/once@1.1.2': resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} @@ -1432,18 +1688,35 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tufjs/canonical-json@2.0.0': + resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@tufjs/models@2.0.1': + resolution: {integrity: sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==} + engines: {node: ^16.14.0 || >=18.0.0} + '@types/babel-types@7.0.16': resolution: {integrity: sha512-5QXs9GBFTNTmilLlWBhnsprqpjfrotyrnzUdwDrywEL/DA4LuCWQT300BTOXA3Y9ngT9F2uvmCoIxI6z8DlJEA==} '@types/babylon@6.16.9': resolution: {integrity: sha512-sEKyxMVEowhcr8WLfN0jJYe4gS4Z9KC2DGz0vqfC7+MXFbmvOF7jSjALC77thvAO2TLgFUPa9vDeOak+AcUrZA==} + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/conventional-commits-parser@5.0.1': resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/google-protobuf@3.15.12': + resolution: {integrity: sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -1453,6 +1726,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} @@ -1471,6 +1747,18 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + + '@types/shimmer@1.2.0': + resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} + + '@types/tmp@0.2.6': + resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} + '@types/uuid@11.0.0': resolution: {integrity: sha512-HVyk8nj2m+jcFRNazzqyVKiZezyhDKrGUA3jlEcg/nZ6Ms+qHwocba1Y/AaVaznJTAM9xpdFSh+ptbNrhOGvZA==} deprecated: This is a stub types definition. uuid provides its own type definitions, so you do not need this installed. @@ -1572,12 +1860,21 @@ packages: '@vitest/utils@2.1.9': resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ace-builds@1.43.3: resolution: {integrity: sha512-MCl9rALmXwIty/4Qboijo/yNysx1r6hBTzG+6n/TiOm5LFhZpEvEIcIITPFiEOEFDfgBOEmxu+a4f54LEFM6Sg==} acorn-globals@3.1.0: resolution: {integrity: sha512-uWttZCk96+7itPxK8xCzY86PnxKTMrReKDqrHzv42VQY0K30PUO8WY13WMOuI+cOdX4EIdzdvQ8k6jkuGRFMYw==} + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1794,6 +2091,10 @@ packages: react: ^17.0.2 react-dom: ^17.0.2 + bin-links@4.0.4: + resolution: {integrity: sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -1824,6 +2125,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -1836,6 +2140,10 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + cacache@18.0.4: + resolution: {integrity: sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==} + engines: {node: ^16.14.0 || >=18.0.0} + cache-point@3.0.1: resolution: {integrity: sha512-itTIMLEKbh6Dw5DruXbxAgcyLnh/oPGVLBfTPqBOftASxHe8bAeXy7JkO4F0LvHqht7XqP5O/09h5UcHS2w0FA==} engines: {node: '>=12.17'} @@ -1845,6 +2153,14 @@ packages: '@75lb/nature': optional: true + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + cachedir@2.3.0: resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} engines: {node: '>=6'} @@ -1931,6 +2247,13 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + clean-css@4.2.4: resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} engines: {node: '>= 4.0'} @@ -1970,14 +2293,25 @@ packages: cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + cliui@9.0.1: resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} engines: {node: '>=20'} + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + cmd-shim@6.0.3: + resolution: {integrity: sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + codecov@3.8.3: resolution: {integrity: sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA==} engines: {node: '>=4.0'} @@ -2022,6 +2356,9 @@ packages: engines: {node: '>= 12'} hasBin: true + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + common-sequence@3.0.0: resolution: {integrity: sha512-g/CgSYk93y+a1IKm50tKl7kaT/OjjTYVQlEbUlt/49ZLV1mcKpUU7iyDiqTAeLdb4QDtQfq3ako8y8v//fzrWQ==} engines: {node: '>=12.17'} @@ -2107,6 +2444,11 @@ packages: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} engines: {node: '>=12'} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + current-module-paths@1.1.2: resolution: {integrity: sha512-H4s4arcLx/ugbu1XkkgSvcUZax0L6tXUqnppGniQb8l5VjUKGHoayXE5RiriiPhYDd+kjZnaok1Uig13PKtKYQ==} engines: {node: '>=12.17'} @@ -2160,6 +2502,10 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} @@ -2177,6 +2523,10 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -2260,6 +2610,12 @@ packages: emojilib@2.4.0: resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -2276,6 +2632,9 @@ packages: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -2452,6 +2811,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -2468,6 +2831,9 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -2604,6 +2970,14 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2651,6 +3025,10 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -2714,10 +3092,17 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} + google-protobuf@3.21.4: + resolution: {integrity: sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -2792,6 +3177,9 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + http-proxy-agent@4.0.1: resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} engines: {node: '>= 6'} @@ -2800,6 +3188,10 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -2808,6 +3200,10 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -2825,12 +3221,20 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} ignore-walk@3.0.4: resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==} + ignore-walk@6.0.5: + resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -2847,6 +3251,9 @@ packages: resolution: {integrity: sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==} engines: {node: '>=18.20'} + import-in-the-middle@1.15.0: + resolution: {integrity: sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==} + import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} @@ -2884,6 +3291,10 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + inquirer@8.2.5: resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} engines: {node: '>=12.0.0'} @@ -2896,6 +3307,10 @@ packages: resolution: {integrity: sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==} engines: {node: '>=12'} + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -2961,6 +3376,9 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -3000,6 +3418,10 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3056,6 +3478,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + issue-parser@7.0.1: resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} engines: {node: ^18.17 || >=20.6.1} @@ -3097,6 +3523,10 @@ packages: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -3165,6 +3595,10 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -3174,6 +3608,9 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-stringify-nice@1.1.4: + resolution: {integrity: sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==} + json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -3186,9 +3623,19 @@ packages: jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + jstransformer@1.0.0: resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} + just-diff-apply@5.5.0: + resolution: {integrity: sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==} + + just-diff@6.0.2: + resolution: {integrity: sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -3273,6 +3720,9 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + longest@1.0.1: resolution: {integrity: sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==} engines: {node: '>=0.10.0'} @@ -3288,6 +3738,10 @@ packages: loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -3314,6 +3768,10 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + make-fetch-happen@13.0.1: + resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==} + engines: {node: ^16.14.0 || >=18.0.0} + markdown-it-anchor@8.6.7: resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} peerDependencies: @@ -3365,6 +3823,11 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + mime@4.0.7: resolution: {integrity: sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ==} engines: {node: '>=16'} @@ -3378,6 +3841,14 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -3399,10 +3870,42 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -3413,6 +3916,9 @@ packages: engines: {node: '>=10'} hasBin: true + module-details-from-path@1.0.4: + resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} @@ -3437,6 +3943,10 @@ packages: resolution: {integrity: sha512-hJ/u2xCpA663h6xyOiztx3y+lg9eU0rdkwJ+c4FtiHo2g/gB0sjXtW31yTdMLWLOIj1gL2FcJMwfOqouuUK/Wg==} engines: {node: '>= 0.4.0'} + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -3460,9 +3970,19 @@ packages: encoding: optional: true + node-gyp@10.3.1: + resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + node-releases@2.0.20: resolution: {integrity: sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==} + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + normalize-package-data@6.0.2: resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} engines: {node: ^16.14.0 || >=18.0.0} @@ -3471,10 +3991,46 @@ packages: resolution: {integrity: sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==} engines: {node: ^20.17.0 || >=22.9.0} + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + normalize-url@8.1.0: resolution: {integrity: sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==} engines: {node: '>=14.16'} + npm-bundled@3.0.1: + resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-install-checks@6.3.0: + resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-normalize-package-bin@3.0.1: + resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@11.0.3: + resolution: {integrity: sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-packlist@8.0.2: + resolution: {integrity: sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-pick-manifest@9.1.0: + resolution: {integrity: sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-registry-fetch@17.1.0: + resolution: {integrity: sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3617,6 +4173,10 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + p-each-series@3.0.0: resolution: {integrity: sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==} engines: {node: '>=12'} @@ -3645,6 +4205,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + p-map@7.0.3: resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} engines: {node: '>=18'} @@ -3657,13 +4221,26 @@ packages: resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} engines: {node: '>=4'} + package-directory@8.1.0: + resolution: {integrity: sha512-qHKRW0pw3lYdZMQVkjDBqh8HlamH/LCww2PH7OWEp4Qrt3SFeYMNpnJrQzlSnGrDD5zGR51XqBh7FnNCdVNEHA==} + engines: {node: '>=18'} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + pacote@18.0.6: + resolution: {integrity: sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-conflict-json@3.0.1: + resolution: {integrity: sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + parse-imports-exports@0.2.4: resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} @@ -3748,6 +4325,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@3.0.1: + resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} + engines: {node: '>=10'} + picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} @@ -3768,6 +4349,10 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -3799,9 +4384,35 @@ packages: resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} engines: {node: '>= 0.6'} + proc-log@4.2.0: + resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + proggy@2.0.0: + resolution: {integrity: sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + promise-all-reject-late@1.0.1: + resolution: {integrity: sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==} + + promise-call-limit@3.0.2: + resolution: {integrity: sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} @@ -3811,6 +4422,10 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + protobufjs@7.5.4: + resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} + engines: {node: '>=12.0.0'} + pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} @@ -3850,6 +4465,9 @@ packages: pug@2.0.4: resolution: {integrity: sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode.js@2.3.1: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} @@ -3864,6 +4482,10 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -3898,6 +4520,14 @@ packages: resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} engines: {node: '>=0.10.0'} + read-cmd-shim@4.0.0: + resolution: {integrity: sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-package-json-fast@3.0.2: + resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + read-package-up@11.0.0: resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} engines: {node: '>=18'} @@ -3952,6 +4582,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-in-the-middle@7.5.2: + resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} + engines: {node: '>=8.6.0'} + requizzle@0.2.4: resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} @@ -3959,6 +4593,9 @@ packages: resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} engines: {node: '>=18'} + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve-dir@1.0.1: resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} engines: {node: '>=0.10.0'} @@ -3976,10 +4613,17 @@ packages: engines: {node: '>= 0.4'} hasBin: true + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -4088,6 +4732,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shimmer@1.2.1: + resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -4118,10 +4765,26 @@ packages: resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} engines: {node: '>=6'} + sigstore@2.3.1: + resolution: {integrity: sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==} + engines: {node: ^16.14.0 || >=18.0.0} + skin-tone@2.0.0: resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} engines: {node: '>=8'} + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + sort-array@5.1.1: resolution: {integrity: sha512-EltS7AIsNlAFIM9cayrgKrM6XP94ATWwXP4LCL4IQbvbYhELSt2hZTrixg+AaQwnWFs/JGJgqU3rxMcNNWxGAA==} engines: {node: '>=12.17'} @@ -4135,6 +4798,9 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map@0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} @@ -4167,6 +4833,10 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -4233,6 +4903,10 @@ packages: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} @@ -4290,6 +4964,10 @@ packages: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + teeny-request@7.1.1: resolution: {integrity: sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==} engines: {node: '>=10'} @@ -4353,6 +5031,10 @@ packages: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + to-fast-properties@1.0.3: resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} engines: {node: '>=0.10.0'} @@ -4375,6 +5057,10 @@ packages: resolution: {integrity: sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==} engines: {node: '>= 0.4'} + treeverse@3.0.0: + resolution: {integrity: sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -4404,6 +5090,10 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tuf-js@2.2.1: + resolution: {integrity: sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==} + engines: {node: ^16.14.0 || >=18.0.0} + tunnel@0.0.6: resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} @@ -4513,6 +5203,14 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-string@3.0.0: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} engines: {node: '>=12'} @@ -4524,6 +5222,10 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + upath@1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -4561,6 +5263,10 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + vite-node@2.1.9: resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -4643,6 +5349,9 @@ packages: resolution: {integrity: sha512-e/FRLDVdZQWFrAzU6Hdvpm7D7m2ina833gIKLptQykRK49mmCYHLHq7UqjPDbxbKLZkTkW1rFqbengdE3sLfdw==} engines: {node: '>=12.17'} + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -4677,6 +5386,11 @@ packages: engines: {node: '>= 8'} hasBin: true + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} @@ -4719,6 +5433,10 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + xmlcreate@2.0.4: resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} @@ -4736,6 +5454,9 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} @@ -4745,6 +5466,10 @@ packages: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + yargs-parser@22.0.0: resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} @@ -4753,6 +5478,10 @@ packages: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yargs@18.0.0: resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} @@ -5728,6 +6457,18 @@ snapshots: '@fastify/busboy@2.1.1': {} + '@grpc/grpc-js@1.14.3': + dependencies: + '@grpc/proto-loader': 0.8.0 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.8.0': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.5.4 + yargs: 17.7.2 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -5754,6 +6495,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/string-locale-compare@1.1.0': {} + '@istanbuljs/schema@0.1.3': {} '@jridgewell/gen-mapping@0.3.13': @@ -5780,10 +6523,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@js-sdsl/ordered-map@4.4.2': {} + '@jsdoc/salty@0.2.9': dependencies: lodash: 4.17.21 + '@logdna/tail-file@2.2.0': {} + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -5800,6 +6547,136 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@npmcli/agent@2.2.2': + dependencies: + agent-base: 7.1.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 10.4.3 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + '@npmcli/arborist@7.5.4': + dependencies: + '@isaacs/string-locale-compare': 1.1.0 + '@npmcli/fs': 3.1.1 + '@npmcli/installed-package-contents': 2.1.0 + '@npmcli/map-workspaces': 3.0.6 + '@npmcli/metavuln-calculator': 7.1.1 + '@npmcli/name-from-folder': 2.0.0 + '@npmcli/node-gyp': 3.0.0 + '@npmcli/package-json': 5.2.1 + '@npmcli/query': 3.1.0 + '@npmcli/redact': 2.0.1 + '@npmcli/run-script': 8.1.0 + bin-links: 4.0.4 + cacache: 18.0.4 + common-ancestor-path: 1.0.1 + hosted-git-info: 7.0.2 + json-parse-even-better-errors: 3.0.2 + json-stringify-nice: 1.1.4 + lru-cache: 10.4.3 + minimatch: 9.0.5 + nopt: 7.2.1 + npm-install-checks: 6.3.0 + npm-package-arg: 11.0.3 + npm-pick-manifest: 9.1.0 + npm-registry-fetch: 17.1.0 + pacote: 18.0.6 + parse-conflict-json: 3.0.1 + proc-log: 4.2.0 + proggy: 2.0.0 + promise-all-reject-late: 1.0.1 + promise-call-limit: 3.0.2 + read-package-json-fast: 3.0.2 + semver: 7.7.3 + ssri: 10.0.6 + treeverse: 3.0.0 + walk-up-path: 3.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.7.3 + + '@npmcli/git@5.0.8': + dependencies: + '@npmcli/promise-spawn': 7.0.2 + ini: 4.1.3 + lru-cache: 10.4.3 + npm-pick-manifest: 9.1.0 + proc-log: 4.2.0 + promise-inflight: 1.0.1 + promise-retry: 2.0.1 + semver: 7.7.3 + which: 4.0.0 + transitivePeerDependencies: + - bluebird + + '@npmcli/installed-package-contents@2.1.0': + dependencies: + npm-bundled: 3.0.1 + npm-normalize-package-bin: 3.0.1 + + '@npmcli/map-workspaces@3.0.6': + dependencies: + '@npmcli/name-from-folder': 2.0.0 + glob: 10.5.0 + minimatch: 9.0.5 + read-package-json-fast: 3.0.2 + + '@npmcli/metavuln-calculator@7.1.1': + dependencies: + cacache: 18.0.4 + json-parse-even-better-errors: 3.0.2 + pacote: 18.0.6 + proc-log: 4.2.0 + semver: 7.7.3 + transitivePeerDependencies: + - bluebird + - supports-color + + '@npmcli/name-from-folder@2.0.0': {} + + '@npmcli/node-gyp@3.0.0': {} + + '@npmcli/package-json@5.2.1': + dependencies: + '@npmcli/git': 5.0.8 + glob: 10.5.0 + hosted-git-info: 7.0.2 + json-parse-even-better-errors: 3.0.2 + normalize-package-data: 6.0.2 + proc-log: 4.2.0 + semver: 7.7.3 + transitivePeerDependencies: + - bluebird + + '@npmcli/promise-spawn@7.0.2': + dependencies: + which: 4.0.0 + + '@npmcli/query@3.1.0': + dependencies: + postcss-selector-parser: 6.1.2 + + '@npmcli/redact@2.0.1': {} + + '@npmcli/run-script@8.1.0': + dependencies: + '@npmcli/node-gyp': 3.0.0 + '@npmcli/package-json': 5.2.1 + '@npmcli/promise-spawn': 7.0.2 + node-gyp: 10.3.1 + proc-log: 4.2.0 + which: 4.0.0 + transitivePeerDependencies: + - bluebird + - supports-color + '@octokit/auth-token@6.0.0': {} '@octokit/core@7.0.3': @@ -5876,6 +6753,86 @@ snapshots: dependencies: '@octokit/openapi-types': 27.0.0 + '@opentelemetry/api-logs@0.55.0': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/api@1.9.0': {} + + '@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.28.0 + + '@opentelemetry/exporter-zipkin@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.28.0 + + '@opentelemetry/instrumentation-grpc@0.55.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.55.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.27.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.55.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.55.0 + '@types/shimmer': 1.2.0 + import-in-the-middle: 1.15.0 + require-in-the-middle: 7.5.2 + semver: 7.7.3 + shimmer: 1.2.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/propagator-b3@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/propagator-jaeger@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.28.0 + + '@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.28.0 + + '@opentelemetry/sdk-trace-node@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) + semver: 7.7.3 + + '@opentelemetry/semantic-conventions@1.27.0': {} + + '@opentelemetry/semantic-conventions@1.28.0': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -5891,6 +6848,112 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@pulumi/aws@7.14.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@pulumi/pulumi': 3.213.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + mime: 2.6.0 + transitivePeerDependencies: + - bluebird + - supports-color + - ts-node + - typescript + + '@pulumi/azure-native@3.11.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@pulumi/pulumi': 3.213.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + transitivePeerDependencies: + - bluebird + - supports-color + - ts-node + - typescript + + '@pulumi/cloudflare@6.11.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@pulumi/pulumi': 3.213.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + transitivePeerDependencies: + - bluebird + - supports-color + - ts-node + - typescript + + '@pulumi/command@1.1.3(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@pulumi/pulumi': 3.213.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + transitivePeerDependencies: + - bluebird + - supports-color + - ts-node + - typescript + + '@pulumi/pulumi@3.213.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@grpc/grpc-js': 1.14.3 + '@logdna/tail-file': 2.2.0 + '@npmcli/arborist': 7.5.4 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/exporter-zipkin': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.55.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-grpc': 0.55.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 1.30.1(@opentelemetry/api@1.9.0) + '@types/google-protobuf': 3.15.12 + '@types/semver': 7.7.1 + '@types/tmp': 0.2.6 + execa: 5.1.1 + fdir: 6.5.0(picomatch@3.0.1) + google-protobuf: 3.21.4 + got: 11.8.6 + ini: 2.0.0 + js-yaml: 3.14.2 + minimist: 1.2.8 + normalize-package-data: 6.0.2 + package-directory: 8.1.0 + picomatch: 3.0.1 + require-from-string: 2.0.2 + semver: 7.7.3 + source-map-support: 0.5.21 + tmp: 0.2.5 + upath: 1.2.0 + optionalDependencies: + ts-node: 10.9.2(@types/node@25.0.3)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - bluebird + - supports-color + + '@pulumi/std@2.2.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@pulumi/pulumi': 3.213.0(ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3))(typescript@5.9.3) + transitivePeerDependencies: + - bluebird + - supports-color + - ts-node + - typescript + '@rollup/rollup-android-arm-eabi@4.53.5': optional: true @@ -6067,6 +7130,38 @@ snapshots: transitivePeerDependencies: - supports-color + '@sigstore/bundle@2.3.2': + dependencies: + '@sigstore/protobuf-specs': 0.3.3 + + '@sigstore/core@1.1.0': {} + + '@sigstore/protobuf-specs@0.3.3': {} + + '@sigstore/sign@2.3.2': + dependencies: + '@sigstore/bundle': 2.3.2 + '@sigstore/core': 1.1.0 + '@sigstore/protobuf-specs': 0.3.3 + make-fetch-happen: 13.0.1 + proc-log: 4.2.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@2.3.4': + dependencies: + '@sigstore/protobuf-specs': 0.3.3 + tuf-js: 2.2.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/verify@1.2.1': + dependencies: + '@sigstore/bundle': 2.3.2 + '@sigstore/core': 1.1.0 + '@sigstore/protobuf-specs': 0.3.3 + '@sindresorhus/base62@1.0.0': {} '@sindresorhus/is@4.6.0': {} @@ -6347,6 +7442,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + '@tootallnate/once@1.1.2': {} '@tsconfig/node10@1.0.11': {} @@ -6357,12 +7456,26 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@tufjs/canonical-json@2.0.0': {} + + '@tufjs/models@2.0.1': + dependencies: + '@tufjs/canonical-json': 2.0.0 + minimatch: 9.0.5 + '@types/babel-types@7.0.16': {} '@types/babylon@6.16.9': dependencies: '@types/babel-types': 7.0.16 + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 25.0.3 + '@types/responselike': 1.0.3 + '@types/conventional-commits-parser@5.0.1': dependencies: '@types/node': 25.0.3 @@ -6370,12 +7483,20 @@ snapshots: '@types/estree@1.0.8': {} + '@types/google-protobuf@3.15.12': {} + + '@types/http-cache-semantics@4.0.4': {} + '@types/istanbul-lib-coverage@2.0.6': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} + '@types/keyv@3.1.4': + dependencies: + '@types/node': 25.0.3 + '@types/linkify-it@5.0.0': {} '@types/lodash@4.17.21': {} @@ -6391,7 +7512,17 @@ snapshots: dependencies: undici-types: 7.16.0 - '@types/normalize-package-data@2.4.4': {} + '@types/normalize-package-data@2.4.4': {} + + '@types/responselike@1.0.3': + dependencies: + '@types/node': 25.0.3 + + '@types/semver@7.7.1': {} + + '@types/shimmer@1.2.0': {} + + '@types/tmp@0.2.6': {} '@types/uuid@11.0.0': dependencies: @@ -6546,12 +7677,18 @@ snapshots: loupe: 3.2.1 tinyrainbow: 1.2.0 + abbrev@2.0.0: {} + ace-builds@1.43.3: {} acorn-globals@3.1.0: dependencies: acorn: 4.0.13 + acorn-import-attributes@1.9.5(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -6766,6 +7903,13 @@ snapshots: - prop-types - supports-color + bin-links@4.0.4: + dependencies: + cmd-shim: 6.0.3 + npm-normalize-package-bin: 3.0.1 + read-cmd-shim: 4.0.0 + write-file-atomic: 5.0.1 + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -6800,6 +7944,8 @@ snapshots: node-releases: 2.0.20 update-browserslist-db: 1.1.3(browserslist@4.25.4) + buffer-from@1.1.2: {} + buffer@5.7.1: dependencies: base64-js: 1.5.1 @@ -6822,10 +7968,37 @@ snapshots: cac@6.7.14: {} + cacache@18.0.4: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.5.0 + lru-cache: 10.4.3 + minipass: 7.1.2 + minipass-collect: 2.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.2.1 + unique-filename: 3.0.0 + cache-point@3.0.1: dependencies: array-back: 6.2.2 + cacheable-lookup@5.0.4: {} + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + cachedir@2.3.0: {} call-bind-apply-helpers@1.0.2: @@ -6905,6 +8078,10 @@ snapshots: check-error@2.1.1: {} + chownr@2.0.0: {} + + cjs-module-lexer@1.4.3: {} + clean-css@4.2.4: dependencies: source-map: 0.6.1 @@ -6950,20 +8127,32 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + cliui@9.0.1: dependencies: string-width: 7.2.0 strip-ansi: 7.1.2 wrap-ansi: 9.0.2 + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + clone@1.0.4: {} - codecov@3.8.3: + cmd-shim@6.0.3: {} + + codecov@3.8.3(encoding@0.1.13): dependencies: argv: 0.0.2 ignore-walk: 3.0.4 js-yaml: 3.14.1 - teeny-request: 7.1.1 + teeny-request: 7.1.1(encoding@0.1.13) urlgrey: 1.0.0 transitivePeerDependencies: - encoding @@ -7019,6 +8208,8 @@ snapshots: - '@types/node' - typescript + common-ancestor-path@1.0.1: {} + common-sequence@3.0.0: {} compare-func@2.0.0: @@ -7102,6 +8293,8 @@ snapshots: dependencies: type-fest: 1.4.0 + cssesc@3.0.0: {} + current-module-paths@1.1.2: {} cz-conventional-changelog@3.3.0(@types/node@25.0.3)(typescript@5.9.3): @@ -7152,6 +8345,10 @@ snapshots: decamelize@1.2.0: {} + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + dedent@0.7.0: {} deep-eql@5.0.2: {} @@ -7164,6 +8361,8 @@ snapshots: dependencies: clone: 1.0.4 + defer-to-connect@2.0.1: {} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 @@ -7240,6 +8439,15 @@ snapshots: emojilib@2.4.0: {} + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + entities@4.5.0: {} env-ci@11.2.0: @@ -7251,6 +8459,8 @@ snapshots: environment@1.1.0: {} + err-code@2.0.3: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -7566,6 +8776,18 @@ snapshots: esutils@2.0.3: {} + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -7599,6 +8821,8 @@ snapshots: expect-type@1.3.0: {} + exponential-backoff@3.1.3: {} + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -7636,6 +8860,10 @@ snapshots: dependencies: reusify: 1.1.0 + fdir@6.5.0(picomatch@3.0.1): + optionalDependencies: + picomatch: 3.0.1 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -7736,6 +8964,14 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + fs.realpath@1.0.0: {} fsevents@2.3.2: @@ -7783,6 +9019,10 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-stream@5.2.0: + dependencies: + pump: 3.0.3 + get-stream@6.0.1: {} get-stream@7.0.1: {} @@ -7867,8 +9107,24 @@ snapshots: define-properties: 1.2.1 gopd: 1.2.0 + google-protobuf@3.21.4: {} + gopd@1.2.0: {} + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -7930,6 +9186,8 @@ snapshots: html-escaper@2.0.2: {} + http-cache-semantics@4.2.0: {} + http-proxy-agent@4.0.1: dependencies: '@tootallnate/once': 1.1.2 @@ -7945,6 +9203,11 @@ snapshots: transitivePeerDependencies: - supports-color + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -7959,6 +9222,8 @@ snapshots: transitivePeerDependencies: - supports-color + human-signals@2.1.0: {} + human-signals@5.0.0: {} human-signals@8.0.1: {} @@ -7969,12 +9234,21 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + ieee754@1.2.1: {} ignore-walk@3.0.4: dependencies: minimatch: 3.1.2 + ignore-walk@6.0.5: + dependencies: + minimatch: 9.0.5 + ignore@5.3.2: {} ignore@7.0.5: {} @@ -7991,6 +9265,13 @@ snapshots: transitivePeerDependencies: - supports-color + import-in-the-middle@1.15.0: + dependencies: + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + cjs-module-lexer: 1.4.3 + module-details-from-path: 1.0.4 + import-meta-resolve@4.2.0: {} imurmurhash@0.1.4: {} @@ -8015,6 +9296,8 @@ snapshots: ini@4.1.1: optional: true + ini@4.1.3: {} + inquirer@8.2.5: dependencies: ansi-escapes: 4.3.2 @@ -8044,6 +9327,8 @@ snapshots: from2: 2.3.0 p-is-promise: 3.0.0 + ip-address@10.1.0: {} + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -8114,6 +9399,8 @@ snapshots: is-interactive@1.0.0: {} + is-lambda@1.0.1: {} + is-map@2.0.3: {} is-negative-zero@2.0.3: {} @@ -8144,6 +9431,8 @@ snapshots: dependencies: call-bound: 1.0.4 + is-stream@2.0.1: {} + is-stream@3.0.0: {} is-stream@4.0.1: {} @@ -8188,6 +9477,8 @@ snapshots: isexe@2.0.0: {} + isexe@3.1.1: {} + issue-parser@7.0.1: dependencies: lodash.capitalize: 4.2.1 @@ -8237,6 +9528,11 @@ snapshots: argparse: 1.0.10 esprima: 4.0.1 + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + js-yaml@4.1.0: dependencies: argparse: 2.0.1 @@ -8318,6 +9614,8 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-parse-even-better-errors@3.0.2: {} + json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: @@ -8325,6 +9623,8 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json-stringify-nice@1.1.4: {} + json5@1.0.2: dependencies: minimist: 1.2.8 @@ -8337,11 +9637,17 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonparse@1.3.1: {} + jstransformer@1.0.0: dependencies: is-promise: 2.2.2 promise: 7.3.1 + just-diff-apply@5.5.0: {} + + just-diff@6.0.2: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -8418,6 +9724,8 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + long@5.3.2: {} + longest@1.0.1: {} longest@2.0.1: {} @@ -8428,6 +9736,8 @@ snapshots: loupe@3.2.1: {} + lowercase-keys@2.0.0: {} + lru-cache@10.4.3: {} lru-cache@11.2.1: {} @@ -8457,6 +9767,23 @@ snapshots: make-error@1.3.6: {} + make-fetch-happen@13.0.1: + dependencies: + '@npmcli/agent': 2.2.2 + cacache: 18.0.4 + http-cache-semantics: 4.2.0 + is-lambda: 1.0.1 + minipass: 7.1.2 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.4 + proc-log: 4.2.0 + promise-retry: 2.0.1 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + markdown-it-anchor@8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.0): dependencies: '@types/markdown-it': 14.1.2 @@ -8503,12 +9830,18 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime@2.6.0: {} + mime@4.0.7: {} mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + min-indent@1.0.1: {} minimatch@10.1.1: @@ -8527,12 +9860,49 @@ snapshots: minimist@1.2.8: {} + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.2 + + minipass-fetch@3.0.5: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + minipass@7.1.2: {} + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + mkdirp@1.0.4: {} mkdirp@3.0.1: {} + module-details-from-path@1.0.4: {} + moment@2.30.1: {} ms@2.1.3: {} @@ -8556,6 +9926,8 @@ snapshots: secure-keys: 1.0.0 yargs: 16.2.0 + negotiator@0.6.4: {} + neo-async@2.6.2: {} nerf-dart@1.0.0: {} @@ -8571,12 +9943,33 @@ snapshots: emojilib: 2.4.0 skin-tone: 2.0.0 - node-fetch@2.7.0: + node-fetch@2.7.0(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-gyp@10.3.1: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + glob: 10.5.0 + graceful-fs: 4.2.11 + make-fetch-happen: 13.0.1 + nopt: 7.2.1 + proc-log: 4.2.0 + semver: 7.7.3 + tar: 6.2.1 + which: 4.0.0 + transitivePeerDependencies: + - supports-color node-releases@2.0.20: {} + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + normalize-package-data@6.0.2: dependencies: hosted-git-info: 7.0.2 @@ -8589,8 +9982,55 @@ snapshots: semver: 7.7.2 validate-npm-package-license: 3.0.4 + normalize-url@6.1.0: {} + normalize-url@8.1.0: {} + npm-bundled@3.0.1: + dependencies: + npm-normalize-package-bin: 3.0.1 + + npm-install-checks@6.3.0: + dependencies: + semver: 7.7.3 + + npm-normalize-package-bin@3.0.1: {} + + npm-package-arg@11.0.3: + dependencies: + hosted-git-info: 7.0.2 + proc-log: 4.2.0 + semver: 7.7.3 + validate-npm-package-name: 5.0.1 + + npm-packlist@8.0.2: + dependencies: + ignore-walk: 6.0.5 + + npm-pick-manifest@9.1.0: + dependencies: + npm-install-checks: 6.3.0 + npm-normalize-package-bin: 3.0.1 + npm-package-arg: 11.0.3 + semver: 7.7.3 + + npm-registry-fetch@17.1.0: + dependencies: + '@npmcli/redact': 2.0.1 + jsonparse: 1.3.1 + make-fetch-happen: 13.0.1 + minipass: 7.1.2 + minipass-fetch: 3.0.5 + minizlib: 2.1.2 + npm-package-arg: 11.0.3 + proc-log: 4.2.0 + transitivePeerDependencies: + - supports-color + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -8682,6 +10122,8 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + p-cancelable@2.1.1: {} + p-each-series@3.0.0: {} p-filter@4.1.0: @@ -8706,18 +10148,55 @@ snapshots: dependencies: p-limit: 3.1.0 + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + p-map@7.0.3: {} p-reduce@3.0.0: {} p-try@1.0.0: {} + package-directory@8.1.0: + dependencies: + find-up-simple: 1.0.1 + package-json-from-dist@1.0.1: {} + pacote@18.0.6: + dependencies: + '@npmcli/git': 5.0.8 + '@npmcli/installed-package-contents': 2.1.0 + '@npmcli/package-json': 5.2.1 + '@npmcli/promise-spawn': 7.0.2 + '@npmcli/run-script': 8.1.0 + cacache: 18.0.4 + fs-minipass: 3.0.3 + minipass: 7.1.2 + npm-package-arg: 11.0.3 + npm-packlist: 8.0.2 + npm-pick-manifest: 9.1.0 + npm-registry-fetch: 17.1.0 + proc-log: 4.2.0 + promise-retry: 2.0.1 + sigstore: 2.3.1 + ssri: 10.0.6 + tar: 6.2.1 + transitivePeerDependencies: + - bluebird + - supports-color + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-conflict-json@3.0.1: + dependencies: + json-parse-even-better-errors: 3.0.2 + just-diff: 6.0.2 + just-diff-apply: 5.5.0 + parse-imports-exports@0.2.4: dependencies: parse-statements: 1.0.11 @@ -8786,6 +10265,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@3.0.1: {} + picomatch@4.0.3: {} pify@3.0.0: {} @@ -8799,6 +10280,11 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -8820,8 +10306,23 @@ snapshots: private@0.1.8: {} + proc-log@4.2.0: {} + process-nextick-args@2.0.1: {} + proggy@2.0.0: {} + + promise-all-reject-late@1.0.1: {} + + promise-call-limit@3.0.2: {} + + promise-inflight@1.0.1: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + promise@7.3.1: dependencies: asap: 2.0.6 @@ -8834,6 +10335,21 @@ snapshots: proto-list@1.2.4: {} + protobufjs@7.5.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 25.0.3 + long: 5.3.2 + pseudomap@1.0.2: {} pug-attrs@2.0.4: @@ -8905,6 +10421,11 @@ snapshots: pug-runtime: 2.0.5 pug-strip-comments: 1.0.4 + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + punycode.js@2.3.1: {} punycode@1.4.1: {} @@ -8913,6 +10434,8 @@ snapshots: queue-microtask@1.2.3: {} + quick-lru@5.1.1: {} + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -8965,6 +10488,13 @@ snapshots: loose-envify: 1.4.0 object-assign: 4.1.1 + read-cmd-shim@4.0.0: {} + + read-package-json-fast@3.0.2: + dependencies: + json-parse-even-better-errors: 3.0.2 + npm-normalize-package-bin: 3.0.1 + read-package-up@11.0.0: dependencies: find-up-simple: 1.0.1 @@ -9046,8 +10576,15 @@ snapshots: require-directory@2.1.1: {} - require-from-string@2.0.2: - optional: true + require-from-string@2.0.2: {} + + require-in-the-middle@7.5.2: + dependencies: + debug: 4.4.3 + module-details-from-path: 1.0.4 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color requizzle@0.2.4: dependencies: @@ -9055,6 +10592,8 @@ snapshots: reserved-identifiers@1.2.0: {} + resolve-alpn@1.2.1: {} + resolve-dir@1.0.1: dependencies: expand-tilde: 2.0.2 @@ -9070,11 +10609,17 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 + retry@0.12.0: {} + reusify@1.1.0: {} right-align@0.1.3: @@ -9235,6 +10780,8 @@ snapshots: shebang-regex@3.0.0: {} + shimmer@1.2.1: {} + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -9275,10 +10822,36 @@ snapshots: figures: 2.0.0 pkg-conf: 2.1.0 + sigstore@2.3.1: + dependencies: + '@sigstore/bundle': 2.3.2 + '@sigstore/core': 1.1.0 + '@sigstore/protobuf-specs': 0.3.3 + '@sigstore/sign': 2.3.2 + '@sigstore/tuf': 2.3.4 + '@sigstore/verify': 1.2.1 + transitivePeerDependencies: + - supports-color + skin-tone@2.0.0: dependencies: unicode-emoji-modifier-base: 1.0.0 + smart-buffer@4.2.0: {} + + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + + socks@2.8.7: + dependencies: + ip-address: 10.1.0 + smart-buffer: 4.2.0 + sort-array@5.1.1: dependencies: array-back: 6.2.2 @@ -9286,6 +10859,11 @@ snapshots: source-map-js@1.2.1: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map@0.5.7: {} source-map@0.6.1: {} @@ -9317,6 +10895,10 @@ snapshots: sprintf-js@1.0.3: {} + ssri@10.0.6: + dependencies: + minipass: 7.1.2 + stackback@0.0.2: {} std-env@3.10.0: {} @@ -9412,6 +10994,8 @@ snapshots: strip-bom@4.0.0: {} + strip-final-newline@2.0.0: {} + strip-final-newline@3.0.0: {} strip-final-newline@4.0.0: {} @@ -9457,11 +11041,20 @@ snapshots: tagged-tag@1.0.0: {} - teeny-request@7.1.1: + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + teeny-request@7.1.1(encoding@0.1.13): dependencies: http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 - node-fetch: 2.7.0 + node-fetch: 2.7.0(encoding@0.1.13) stream-events: 1.0.5 uuid: 8.3.2 transitivePeerDependencies: @@ -9527,6 +11120,8 @@ snapshots: dependencies: os-tmpdir: 1.0.2 + tmp@0.2.5: {} + to-fast-properties@1.0.3: {} to-regex-range@5.0.1: @@ -9544,6 +11139,8 @@ snapshots: traverse@0.6.8: {} + treeverse@3.0.0: {} + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -9577,6 +11174,14 @@ snapshots: tslib@2.8.1: {} + tuf-js@2.2.1: + dependencies: + '@tufjs/models': 2.0.1 + debug: 4.4.3 + make-fetch-happen: 13.0.1 + transitivePeerDependencies: + - supports-color + tunnel@0.0.6: {} type-check@0.4.0: @@ -9674,6 +11279,14 @@ snapshots: unicorn-magic@0.3.0: {} + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + unique-string@3.0.0: dependencies: crypto-random-string: 4.0.0 @@ -9682,6 +11295,8 @@ snapshots: universalify@2.0.1: {} + upath@1.2.0: {} + update-browserslist-db@1.1.3(browserslist@4.25.4): dependencies: browserslist: 4.25.4 @@ -9717,6 +11332,8 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + validate-npm-package-name@5.0.1: {} + vite-node@2.1.9(@types/node@25.0.3): dependencies: cac: 6.7.14 @@ -9807,6 +11424,8 @@ snapshots: walk-back@5.1.1: {} + walk-up-path@3.0.1: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 @@ -9867,6 +11486,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@4.0.0: + dependencies: + isexe: 3.1.1 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -9907,6 +11530,11 @@ snapshots: wrappy@1.0.2: {} + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + xmlcreate@2.0.4: {} xtend@4.0.2: {} @@ -9917,10 +11545,14 @@ snapshots: yallist@3.1.1: {} + yallist@4.0.0: {} + yaml@2.8.2: {} yargs-parser@20.2.9: {} + yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} yargs@16.2.0: @@ -9933,6 +11565,16 @@ snapshots: y18n: 5.0.8 yargs-parser: 20.2.9 + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + 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 + yargs@18.0.0: dependencies: cliui: 9.0.1 From d9fd52c462c7960354c9a9f5a8bdf16a55151432 Mon Sep 17 00:00:00 2001 From: Srinidhi Veeraraghavan Date: Fri, 19 Dec 2025 17:59:15 +0000 Subject: [PATCH 2/7] feat: convert cloudflare contructs to pulumi --- src/lib/cloudflare/common/constants.ts | 5 - src/lib/cloudflare/common/construct.ts | 83 ++------- src/lib/cloudflare/common/index.ts | 1 - src/lib/cloudflare/common/stack.ts | 122 ++++++------ src/lib/cloudflare/common/types.ts | 17 +- .../construct/pages-static-site/main.ts | 66 +++---- .../cloudflare/construct/worker-site/main.ts | 83 +++------ src/lib/cloudflare/index.ts | 1 - src/lib/cloudflare/services/access/main.ts | 175 ++++++------------ src/lib/cloudflare/services/access/types.ts | 46 ++--- .../cloudflare/services/api-shield/main.ts | 79 ++------ .../cloudflare/services/api-shield/types.ts | 22 ++- src/lib/cloudflare/services/argo/main.ts | 32 +--- src/lib/cloudflare/services/argo/types.ts | 7 +- src/lib/cloudflare/services/filter/main.ts | 15 +- src/lib/cloudflare/services/filter/types.ts | 4 +- src/lib/cloudflare/services/firewall/main.ts | 15 +- src/lib/cloudflare/services/firewall/types.ts | 4 +- src/lib/cloudflare/services/page/main.ts | 55 ++---- src/lib/cloudflare/services/page/types.ts | 10 +- src/lib/cloudflare/services/record/main.ts | 15 +- src/lib/cloudflare/services/record/types.ts | 4 +- src/lib/cloudflare/services/rule-set/main.ts | 19 +- src/lib/cloudflare/services/rule-set/types.ts | 4 +- src/lib/cloudflare/services/worker/main.ts | 67 ++----- src/lib/cloudflare/services/worker/types.ts | 26 +-- src/lib/cloudflare/services/zone/main.ts | 143 ++++---------- src/lib/cloudflare/services/zone/types.ts | 41 ++-- src/lib/cloudflare/utils/index.ts | 23 --- src/lib/common/types.ts | 5 + 30 files changed, 386 insertions(+), 803 deletions(-) delete mode 100644 src/lib/cloudflare/common/constants.ts delete mode 100644 src/lib/cloudflare/utils/index.ts diff --git a/src/lib/cloudflare/common/constants.ts b/src/lib/cloudflare/common/constants.ts deleted file mode 100644 index 9b54849b..00000000 --- a/src/lib/cloudflare/common/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum RemoteBackend { - local = 'local', - s3 = 's3', - azurerm = 'azurerm', -} diff --git a/src/lib/cloudflare/common/construct.ts b/src/lib/cloudflare/common/construct.ts index daf8a1d1..e33ed660 100644 --- a/src/lib/cloudflare/common/construct.ts +++ b/src/lib/cloudflare/common/construct.ts @@ -1,8 +1,5 @@ -import { AwsProvider } from '@cdktf/provider-aws/lib/provider/index.js' -import { CloudflareProvider } from '@cdktf/provider-cloudflare/lib/provider/index.js' -import { AzurermProvider } from '@cdktf/provider-azurerm/lib/provider/index.js' -import { AzurermBackend, S3Backend, TerraformStack, TerraformVariable } from 'cdktf' -import { Construct } from 'constructs' +import { Provider as CloudflareProvider } from '@pulumi/cloudflare' +import { ComponentResource, ComponentResourceOptions, Config } from '@pulumi/pulumi' import { isDevStage, isPrdStage, isTestStage, isUatStage } from '../../common/index.js' import { CloudflareAccessManager, @@ -16,12 +13,13 @@ import { CloudflareWorkerManager, CloudflareZoneManager, } from '../services/index.js' -import { RemoteBackend } from './constants.js' import { CommonCloudflareStackProps } from './types.js' -export class CommonCloudflareConstruct extends TerraformStack { +export class CommonCloudflareConstruct extends ComponentResource { declare props: CommonCloudflareStackProps + declare options?: ComponentResourceOptions id: string + config: Config fullyQualifiedDomainName: string accessManager: CloudflareAccessManager apiShieldManager: CloudflareApiShieldManager @@ -33,15 +31,13 @@ export class CommonCloudflareConstruct extends TerraformStack { ruleSetManager: CloudflareRuleSetManager workerManager: CloudflareWorkerManager zoneManager: CloudflareZoneManager - awsProvider: AwsProvider - s3Backend: S3Backend - azurermProvider: AzurermProvider - azurermBackend: AzurermBackend + provider: CloudflareProvider - constructor(scope: Construct, id: string, props: CommonCloudflareStackProps) { - super(scope, id) + constructor(name: string, props: CommonCloudflareStackProps, options?: ComponentResourceOptions) { + super(`custom:cloudflare:Construct:${name}`, name, props, options) this.props = props - this.id = id + this.options = options + this.id = name this.accessManager = new CloudflareAccessManager() this.apiShieldManager = new CloudflareApiShieldManager() @@ -54,11 +50,10 @@ export class CommonCloudflareConstruct extends TerraformStack { this.workerManager = new CloudflareWorkerManager() this.zoneManager = new CloudflareZoneManager() + /* initialise config */ + this.config = new Config() this.determineFullyQualifiedDomain() - this.determineAccountId() - this.determineApiToken() - this.determineRemoteBackend() - new CloudflareProvider(this, `${this.id}-provider`, this.props) + this.provider = new CloudflareProvider(`${this.id}-provider`, this.props, options) } /** @@ -70,58 +65,6 @@ export class CommonCloudflareConstruct extends TerraformStack { : this.props.domainName } - /** - * @summary Determine the account id based on the cdktf.json context - */ - protected determineAccountId() { - this.props.accountId = new TerraformVariable(this, `accountId`, {}).stringValue - } - - /** - * @summary Determine the api token based on the cdktf.json context - */ - protected determineApiToken() { - this.props.apiToken = new TerraformVariable(this, `apiToken`, {}).stringValue - } - - protected determineRemoteBackend() { - const debug = this.node.tryGetContext('debug') - - switch (this.props.remoteBackend?.type) { - case RemoteBackend.s3: - this.awsProvider = new AwsProvider(this, `${this.id}-aws-provider`, { - profile: process.env.AWS_PROFILE, - region: this.props.remoteBackend.region, - }) - this.s3Backend = new S3Backend(this, { - bucket: this.props.remoteBackend.bucketName, - dynamodbTable: this.props.remoteBackend.tableName, - key: `${this.id}`, - profile: process.env.AWS_PROFILE, - region: this.props.remoteBackend.region, - }) - break - case RemoteBackend.azurerm: - this.azurermProvider = new AzurermProvider(this, `${this.id}-azurerm-provider`, { - features: [{}], - subscriptionId: this.props.remoteBackend.subscriptionId, - }) - this.azurermBackend = new AzurermBackend(this, { - storageAccountName: this.props.remoteBackend.storageAccountName, - containerName: this.props.remoteBackend.containerName, - key: `${this.id}`, - subscriptionId: this.props.remoteBackend.subscriptionId, - resourceGroupName: this.props.remoteBackend.resourceGroupName, - }) - break - case RemoteBackend.local: - if (debug) console.debug(`Using local backend for ${this.id}`) - break - default: - break - } - } - /** * @summary Utility method to determine if the initialisation is in development (dev) stage * This is determined by the stage property injected via cdk context diff --git a/src/lib/cloudflare/common/index.ts b/src/lib/cloudflare/common/index.ts index 3cd27e15..65ef9371 100644 --- a/src/lib/cloudflare/common/index.ts +++ b/src/lib/cloudflare/common/index.ts @@ -1,4 +1,3 @@ -export * from './constants.js' export * from './construct.js' export * from './stack.js' export * from './types.js' diff --git a/src/lib/cloudflare/common/stack.ts b/src/lib/cloudflare/common/stack.ts index 34d2bc95..4b73f56b 100644 --- a/src/lib/cloudflare/common/stack.ts +++ b/src/lib/cloudflare/common/stack.ts @@ -1,13 +1,11 @@ -import fs from 'fs' -import { CommonCloudflareConstruct } from './construct.js' -import { CommonCloudflareStackProps } from './types.js' - +import { ComponentResource, ComponentResourceOptions, Config } from '@pulumi/pulumi' import appRoot from 'app-root-path' -import { TerraformStack } from 'cdktf' -import { Construct } from 'constructs' +import fs from 'fs' import _ from 'lodash' import path from 'path' import { isDevStage } from '../../common/index.js' +import { CommonCloudflareConstruct } from './construct.js' +import { CommonCloudflareStackProps } from './types.js' /** * @classdesc Common stack to use as a base for all higher level constructs. @@ -21,19 +19,16 @@ import { isDevStage } from '../../common/index.js' * } * } */ -export class CommonCloudflareStack extends TerraformStack { +export class CommonCloudflareStack extends ComponentResource { construct: CommonCloudflareConstruct props: CommonCloudflareStackProps + config: Config - constructor(parent: Construct, name: string, props: CommonCloudflareStackProps) { - super(parent, name) - - /* determine extra cdk contexts */ - this.determineExtraContexts() - - /* determine extra cdk stage contexts */ - this.determineStageContexts() + constructor(name: string, props: CommonCloudflareStackProps, options?: ComponentResourceOptions) { + super(`custom:cloudflare:Stack:${name}`, name, props, options) + /* initialise config */ + this.config = new Config() this.props = this.determineConstructProps(props) } @@ -43,17 +38,27 @@ export class CommonCloudflareStack extends TerraformStack { * @returns The stack properties */ protected determineConstructProps(props: CommonCloudflareStackProps) { - const stage = this.node.tryGetContext('stage') + let projectProps: CommonCloudflareStackProps = props + if (!projectProps) { + const projectPropsPath = path.join(appRoot.path, 'pulumi.json') + if (!fs.existsSync(projectPropsPath)) throw `Context properties unavailable in path:${projectPropsPath}` + + const projectPropsBuffer = fs.readFileSync(projectPropsPath) + projectProps = JSON.parse(projectPropsBuffer.toString('utf-8')) + } + return { - accountId: this.node.tryGetContext('accountId'), - apiToken: this.node.tryGetContext('apiToken'), - domainName: this.node.tryGetContext('domainName'), - extraContexts: this.node.tryGetContext('extraContexts'), - features: this.node.tryGetContext('features'), - name: this.node.tryGetContext('resourceGroupName'), - skipStageForARecords: this.node.tryGetContext('skipStageForARecords'), - stage: stage, - subDomain: this.node.tryGetContext('subDomain'), + accountId: projectProps.accountId, + apiToken: projectProps.apiToken, + domainName: projectProps.domainName, + extraContexts: projectProps.extraContexts, + name: projectProps.resourceGroupName ?? projectProps.name, + skipStageForARecords: projectProps.skipStageForARecords, + stage: projectProps.stage, + stageContextPath: projectProps.stageContextPath, + subDomain: projectProps.subDomain, + ...this.determineExtraContexts(props), + ...this.determineStageContexts(props), } } @@ -62,16 +67,15 @@ export class CommonCloudflareStack extends TerraformStack { * - Sets the properties from the extra contexts into cdk node context * - Primary use is to have layered config in separate files to enable easier maintenance and readability */ - protected determineExtraContexts() { - const extraContexts = this.node.tryGetContext('extraContexts') - const debug = this.node.tryGetContext('debug') - - if (!extraContexts) { - if (debug) console.debug(`No additional contexts provided. Using default context properties from cdktf.json`) - return + protected determineExtraContexts(props: CommonCloudflareStackProps) { + if (!props.extraContexts) { + if (props.debug) + console.debug(`No additional contexts provided. Using default context properties from cdktf.json`) + return {} } - _.forEach(extraContexts, (context: string) => { + let extraContextProps: Record = {} + _.forEach(props.extraContexts, (context: string) => { const extraContextPath = path.join(appRoot.path, context) /* scenario where extra context is configured in cdk.json but absent in file system */ @@ -79,16 +83,15 @@ export class CommonCloudflareStack extends TerraformStack { /* read the extra properties */ const extraContextPropsBuffer = fs.readFileSync(extraContextPath) - if (debug) console.debug(`Adding additional contexts provided in ${extraContextPath}`) + if (props.debug) console.debug(`Adding additional contexts provided in ${extraContextPath}`) /* parse as JSON properties */ - const extraContextProps = JSON.parse(extraContextPropsBuffer.toString('utf-8')) - - /* set each of the property into the cdk node context */ - _.keys(extraContextProps).forEach((propKey: any) => { - this.node.setContext(propKey, extraContextProps[propKey]) - }) + extraContextProps = { + ...extraContextProps, + ...JSON.parse(extraContextPropsBuffer.toString('utf-8')), + } }) + return extraContextProps } /** @@ -96,48 +99,35 @@ export class CommonCloudflareStack extends TerraformStack { * - Sets the properties from the extra stage contexts into cdk node context * - Primary use is to have layered config for each environment which is injected into the context */ - protected determineStageContexts() { - const stage = process.env.STAGE ?? this.node.tryGetContext('stage') - const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv' - const stageContextFilePath = path.join(appRoot.path, stageContextPath, `${stage}.json`) - const debug = this.node.tryGetContext('debug') - - if (isDevStage(stage)) { - if (debug) console.debug(`Development stage. Using default stage context properties`) + protected determineStageContexts(props: CommonCloudflareStackProps) { + const stageContextFilePath = path.join(appRoot.path, props.stageContextPath ?? 'cdkEnv', `${props.stage}.json`) + + if (isDevStage(props.stage)) { + if (props.debug) console.debug(`Development stage. Using default stage context properties`) } /* alert default context usage when extra stage config is missing */ if (!fs.existsSync(stageContextFilePath)) { - if (debug) console.debug(`Stage specific context properties unavailable in path:${stageContextFilePath}`) - if (debug) console.debug(`Using default stage context properties for ${stage} stage`) - return + if (props.debug) console.debug(`Stage specific context properties unavailable in path:${stageContextFilePath}`) + if (props.debug) console.debug(`Using default stage context properties for ${props.stage} stage`) + return {} } /* read the extra properties */ const stageContextPropsBuffer = fs.readFileSync(stageContextFilePath) - if (debug) console.debug(`Adding additional stage contexts provided in ${stageContextFilePath}`) + if (props.debug) console.debug(`Adding additional stage contexts provided in ${stageContextFilePath}`) /* parse as JSON properties */ - const stageContextProps = JSON.parse(stageContextPropsBuffer.toString('utf-8')) - - /* set each of the property into the cdk node context */ - _.keys(stageContextProps).forEach((propKey: any) => { - /* handle object, array properties */ - if (typeof stageContextProps[propKey] === 'object' && !Array.isArray(stageContextProps[propKey])) { - this.node.setContext(propKey, _.merge(this.node.tryGetContext(propKey), stageContextProps[propKey])) - } else { - /* handle all other primitive properties */ - this.node.setContext(propKey, stageContextProps[propKey]) - } - }) + return JSON.parse(stageContextPropsBuffer.toString('utf-8')) } /** * @summary Determine the fully qualified domain name based on domainName & subDomain */ protected fullyQualifiedDomain() { - const domainName = this.node.tryGetContext('domainName') - const subDomain = this.node.tryGetContext('subDomain') + const domainName = this.props.domainName + const subDomain = this.props.subDomain + return subDomain ? `${subDomain}.${domainName}` : domainName } } diff --git a/src/lib/cloudflare/common/types.ts b/src/lib/cloudflare/common/types.ts index 0bb7d6d1..7ef8fe01 100644 --- a/src/lib/cloudflare/common/types.ts +++ b/src/lib/cloudflare/common/types.ts @@ -1,23 +1,10 @@ -import { CloudflareProviderConfig } from '@cdktf/provider-cloudflare/lib/provider/index.js' import { BaseProps } from '../../common/index.js' -import { RemoteBackend } from './constants.js' - -export interface RemoteBackendProps { - bucketName: string - region: string - tableName: string - type: RemoteBackend - storageAccountName: string - containerName: string - subscriptionId: string - resourceGroupName: string -} /** */ -export interface CommonCloudflareStackProps extends BaseProps, CloudflareProviderConfig { +export interface CommonCloudflareStackProps extends BaseProps { accountId: string apiToken: string - remoteBackend?: RemoteBackendProps + resourceGroupName?: string useExistingZone?: boolean } diff --git a/src/lib/cloudflare/construct/pages-static-site/main.ts b/src/lib/cloudflare/construct/pages-static-site/main.ts index 6f42e202..0c237646 100644 --- a/src/lib/cloudflare/construct/pages-static-site/main.ts +++ b/src/lib/cloudflare/construct/pages-static-site/main.ts @@ -1,18 +1,12 @@ -import { DataAwsSecretsmanagerSecretVersion } from '@cdktf/provider-aws/lib/data-aws-secretsmanager-secret-version/index.js' -import { DataAwsSecretsmanagerSecret } from '@cdktf/provider-aws/lib/data-aws-secretsmanager-secret/index.js' -import { DataAzurermKeyVaultSecret } from '@cdktf/provider-azurerm/lib/data-azurerm-key-vault-secret/index.js' -import { DataAzurermKeyVault } from '@cdktf/provider-azurerm/lib/data-azurerm-key-vault/index.js' -import { DataCloudflareZone } from '@cdktf/provider-cloudflare/lib/data-cloudflare-zone/index.js' -import { DnsRecord } from '@cdktf/provider-cloudflare/lib/dns-record/index.js' -import { PagesDomain } from '@cdktf/provider-cloudflare/lib/pages-domain/index.js' import { - PagesProject, PagesProjectDeploymentConfigsPreviewEnvVars, PagesProjectDeploymentConfigsProductionEnvVars, } from '@cdktf/provider-cloudflare/lib/pages-project/index.js' -import { Zone } from '@cdktf/provider-cloudflare/lib/zone/index.js' -import { Fn } from 'cdktf' -import { Construct } from 'constructs' +import * as aws from '@pulumi/aws' +import * as azure from '@pulumi/azure-native' +import { DnsRecord, PagesDomain, PagesProject, Zone } from '@pulumi/cloudflare' +import { ComponentResourceOptions } from '@pulumi/pulumi' +import * as std from '@pulumi/std' import { CommonCloudflareConstruct } from '../../common/index.js' import { CloudflarePagesStaticSiteProps } from './types.js' @@ -38,16 +32,17 @@ export class CloudflarePagesStaticSite extends CommonCloudflareConstruct { sitePagesCnameRecord: DnsRecord sitePagesDomain: PagesDomain sitePagesProject: PagesProject - siteZone: DataCloudflareZone | Zone + siteZone: Zone sitePagesEnvironmentVariables: { [key: string]: PagesProjectDeploymentConfigsProductionEnvVars } sitePagesPreviewEnvironmentVariables: { [key: string]: PagesProjectDeploymentConfigsPreviewEnvVars } sitePagesSecrets: { [key: string]: PagesProjectDeploymentConfigsProductionEnvVars } sitePagesPreviewSecrets: { [key: string]: PagesProjectDeploymentConfigsPreviewEnvVars } siteDeploymentDependsOn: any - constructor(parent: Construct, id: string, props: CloudflarePagesStaticSiteProps) { - super(parent, id, props) + constructor(id: string, props: CloudflarePagesStaticSiteProps, options?: ComponentResourceOptions) { + super(id, props) this.props = props + this.options = options this.id = id } @@ -115,15 +110,12 @@ export class CloudflarePagesStaticSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected resolveSecretFromAWS(secretName: string, secretKey: string) { - if (!this.awsProvider) return - const secret = new DataAwsSecretsmanagerSecret(this, `${this.id}-${secretName}-${secretKey}`, { name: secretName }) - const secretVersion = new DataAwsSecretsmanagerSecretVersion(this, `${this.id}-${secretName}-${secretKey}-ver`, { - provider: this.awsProvider, - secretId: secret.id, - }) + protected async resolveSecretFromAWS(secretName: string, secretKey: string) { + if (this.config.require('secretsProvider') !== 'aws') return + const secret = await aws.secretsmanager.getSecret({ name: secretName }) + const secretVersion = await aws.secretsmanager.getSecretVersion({ secretId: secret.id }) if (!secretVersion) throw new Error(`Unable to resolve secret:${secretName}`) - return Fn.lookup(Fn.jsondecode(secretVersion.secretString), secretKey) + return await std.jsondecode({ input: secretVersion.secretString }) } /** @@ -134,27 +126,15 @@ export class CloudflarePagesStaticSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string) { - const keyVaultData = new DataAzurermKeyVault( - this, - `${this.id}-${resourceGroupName}-${keyVaultName}-${secretKey}-vault`, - { - resourceGroupName: resourceGroupName, - name: keyVaultName, - provider: this.azurermProvider, - } - ) - const secretValueData = new DataAzurermKeyVaultSecret( - this, - `${this.id}-${resourceGroupName}-${keyVaultName}-${secretKey}-secret`, - { - name: secretKey, - keyVaultId: keyVaultData.id, - provider: this.azurermProvider, - } - ) + protected async resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string) { + if (this.config.require('secretsProvider') !== 'azure') return + const secretValueData = await azure.keyvault.getSecret({ + resourceGroupName, + secretName: secretKey, + vaultName: keyVaultName, + }) if (!secretValueData) throw new Error(`Unable to resolve secret:${secretKey}`) - return secretValueData.value + return secretValueData.properties?.value } /** @@ -201,7 +181,7 @@ export class CloudflarePagesStaticSite extends CommonCloudflareConstruct { branch: this.props.siteBranch ?? 'main', directory: this.props.siteAssetDir, message: this.props.siteDeployMessage, - projectName: this.sitePagesProject.name, + projectName: String(this.sitePagesProject.name), dependsOn: this.siteDeploymentDependsOn, }) } diff --git a/src/lib/cloudflare/construct/worker-site/main.ts b/src/lib/cloudflare/construct/worker-site/main.ts index 14cb16a9..a2589f51 100644 --- a/src/lib/cloudflare/construct/worker-site/main.ts +++ b/src/lib/cloudflare/construct/worker-site/main.ts @@ -1,12 +1,9 @@ -import { DataAwsSecretsmanagerSecretVersion } from '@cdktf/provider-aws/lib/data-aws-secretsmanager-secret-version/index.js' -import { DataAwsSecretsmanagerSecret } from '@cdktf/provider-aws/lib/data-aws-secretsmanager-secret/index.js' -import { DataAzurermKeyVaultSecret } from '@cdktf/provider-azurerm/lib/data-azurerm-key-vault-secret/index.js' -import { DataAzurermKeyVault } from '@cdktf/provider-azurerm/lib/data-azurerm-key-vault/index.js' -import { DataCloudflareZone } from '@cdktf/provider-cloudflare/lib/data-cloudflare-zone/index.js' -import { WorkersScript, WorkersScriptBindings } from '@cdktf/provider-cloudflare/lib/workers-script/index.js' -import { Zone } from '@cdktf/provider-cloudflare/lib/zone/index.js' -import { AssetType, Fn, TerraformAsset } from 'cdktf' -import { Construct } from 'constructs' +import { WorkersScriptBindings } from '@cdktf/provider-cloudflare/lib/workers-script/index.js' +import * as aws from '@pulumi/aws' +import * as azure from '@pulumi/azure-native' +import { WorkersScript, Zone } from '@pulumi/cloudflare' +import { ComponentResourceOptions } from '@pulumi/pulumi' +import * as std from '@pulumi/std' import { CommonCloudflareConstruct } from '../../common/index.js' import { CloudflareWorkerSiteProps } from './types.js' @@ -29,14 +26,15 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { declare props: CloudflareWorkerSiteProps /* worker site resources */ - siteZone: DataCloudflareZone | Zone + siteZone: Zone siteWorkerScript: WorkersScript workerPlainTextBindingEnvironmentVariables: WorkersScriptBindings[] = [] workerSecretTextBindingEnvironmentVariables: WorkersScriptBindings[] = [] - constructor(parent: Construct, id: string, props: CloudflareWorkerSiteProps) { - super(parent, id, props) + constructor(id: string, props: CloudflareWorkerSiteProps, options?: ComponentResourceOptions) { + super(id, props) this.props = props + this.options = options this.id = id } @@ -78,15 +76,14 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { /** * @summary Create the worker */ - protected createWorker() { - const workerContent = new TerraformAsset(this, `${this.id}-worker-content`, { - path: this.props.siteWorkerAsset, - type: AssetType.FILE, + protected async createWorker() { + const workerContent = std.file({ + input: this.props.siteWorkerAsset, }) this.siteWorkerScript = this.workerManager.createWorkerScript(`${this.id}-worker-script`, this, { ...this.props.siteWorkerScript, - content: Fn.file(workerContent.path), + content: (await workerContent).result, }) } @@ -108,23 +105,12 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected resolveSecretFromAWS(secretName: string, secretKey: string, id?: string) { - if (!this.awsProvider) { - throw new Error(`Unable to resolve secret:${secretKey}. AWS provider not found`) - } - const secret = new DataAwsSecretsmanagerSecret(this, id ?? `${this.id}-${secretName}-${secretKey}`, { - name: secretName, - }) - const secretVersion = new DataAwsSecretsmanagerSecretVersion( - this, - id ? `${id}-ver` : `${this.id}-${secretName}-${secretKey}-ver`, - { - provider: this.awsProvider, - secretId: secret.id, - } - ) + protected async resolveSecretFromAWS(secretName: string, secretKey: string) { + if (this.config.require('secretsProvider') !== 'aws') return + const secret = await aws.secretsmanager.getSecret({ name: secretName }) + const secretVersion = await aws.secretsmanager.getSecretVersion({ secretId: secret.id }) if (!secretVersion) throw new Error(`Unable to resolve secret:${secretName}`) - return Fn.lookup(Fn.jsondecode(secretVersion.secretString), secretKey) + return await std.jsondecode({ input: secretVersion.secretString }) } /** @@ -135,30 +121,15 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string, id?: string) { - if (!this.azurermProvider) { - throw new Error(`Unable to resolve secret:${secretKey}. Azurerm provider not found`) - } - const keyVaultData = new DataAzurermKeyVault( - this, - id ? `${id}-vault` : `${this.id}-${resourceGroupName}-${keyVaultName}-${secretKey}-vault`, - { - resourceGroupName: resourceGroupName, - name: keyVaultName, - provider: this.azurermProvider, - } - ) - const secretValueData = new DataAzurermKeyVaultSecret( - this, - id ? `${id}-secret` : `${this.id}-${resourceGroupName}-${keyVaultName}-${secretKey}-secret`, - { - name: secretKey, - keyVaultId: keyVaultData.id, - provider: this.azurermProvider, - } - ) + protected async resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string) { + if (this.config.require('secretsProvider') !== 'azure') return + const secretValueData = await azure.keyvault.getSecret({ + resourceGroupName, + secretName: secretKey, + vaultName: keyVaultName, + }) if (!secretValueData) throw new Error(`Unable to resolve secret:${secretKey}`) - return secretValueData.value + return secretValueData.properties?.value } /** diff --git a/src/lib/cloudflare/index.ts b/src/lib/cloudflare/index.ts index 415cf44f..16e1610e 100644 --- a/src/lib/cloudflare/index.ts +++ b/src/lib/cloudflare/index.ts @@ -2,4 +2,3 @@ export * from './common/index.js' export * from './construct/index.js' export * from './services/index.js' export * from './types/index.js' -export * from './utils/index.js' diff --git a/src/lib/cloudflare/services/access/main.ts b/src/lib/cloudflare/services/access/main.ts index fd320874..c276abc0 100644 --- a/src/lib/cloudflare/services/access/main.ts +++ b/src/lib/cloudflare/services/access/main.ts @@ -1,16 +1,5 @@ -import { AccessRule } from '@cdktf/provider-cloudflare/lib/access-rule/index.js' -import { ZeroTrustAccessApplication } from '@cdktf/provider-cloudflare/lib/zero-trust-access-application/index.js' -import { ZeroTrustAccessCustomPage } from '@cdktf/provider-cloudflare/lib/zero-trust-access-custom-page/index.js' -import { ZeroTrustAccessGroup } from '@cdktf/provider-cloudflare/lib/zero-trust-access-group/index.js' -import { ZeroTrustAccessIdentityProvider } from '@cdktf/provider-cloudflare/lib/zero-trust-access-identity-provider/index.js' -import { ZeroTrustAccessMtlsCertificate } from '@cdktf/provider-cloudflare/lib/zero-trust-access-mtls-certificate/index.js' -import { ZeroTrustAccessPolicy } from '@cdktf/provider-cloudflare/lib/zero-trust-access-policy/index.js' -import { ZeroTrustAccessServiceToken } from '@cdktf/provider-cloudflare/lib/zero-trust-access-service-token/index.js' -import { ZeroTrustAccessShortLivedCertificate } from '@cdktf/provider-cloudflare/lib/zero-trust-access-short-lived-certificate/index.js' -import { ZeroTrustAccessTag } from '@cdktf/provider-cloudflare/lib/zero-trust-access-tag/index.js' -import { ZeroTrustOrganization } from '@cdktf/provider-cloudflare/lib/zero-trust-organization/index.js' -import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' +import * as cloudflare from '@pulumi/cloudflare' +import { CommonCloudflareConstruct } from '../../common/construct.js' import { AccessRuleProps, ZeroTrustAccessApplicationProps, @@ -27,17 +16,16 @@ import { /** * @classdesc Provides operations on Cloudflare Access - * - A new instance of this class is injected into {@link CommonCloudflareConstruct} constructor. - * - If a custom construct extends {@link CommonCloudflareConstruct}, an instance is available within the context. + * - A new instance of this class is injected into {@link CommonCloudflareComponent} constructor. + * - If a custom component extends {@link CommonCloudflareComponent}, an instance is available within the context. * @example * ``` - * import { CommonCloudflareConstruct, CommonCloudflareConstruct } from '@gradientedge/cdk-utils' + * import { CommonCloudflareComponent, CloudflareAccessManager } from '@gradientedge/cdk-utils' * - * class CustomConstruct extends CommonCloudflareConstruct { - * constructor(parent: Construct, id: string, props: CommonCloudflareStackProps) { - * super(parent, id, props) - * this.props = props - * this.accessManager.createApiShield('MyAppAccess', this, props) + * class CustomComponent extends CommonCloudflareComponent { + * constructor(name: string, args: any, opts?: pulumi.ComponentResourceOptions) { + * super(name, args, opts) + * this.accessManager.createAccessApplication('MyAppAccess', this, props) * } * } * ``` @@ -48,34 +36,31 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access application properties - * @see [CDKTF Access Application Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessApplication.typescript.md} + * @see [Pulumi Cloudflare Access Application]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccessapplication/} */ public createAccessApplication(id: string, scope: CommonCloudflareConstruct, props: ZeroTrustAccessApplicationProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessApplication = new ZeroTrustAccessApplication(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessApplication(`${id}`, { ...props, domain: `${props.domain}-${scope.props.domainName}`, name: `${props.name}-${scope.props.stage}`, zoneId, }) - - createCloudflareTfOutput(`${id}-accessApplicationFriendlyUniqueId`, scope, accessApplication.friendlyUniqueId) - createCloudflareTfOutput(`${id}-accessApplicationId`, scope, accessApplication.id) - - return accessApplication } /** * @summary Method to create a new Cloudflare Application Access Short Lived Certificate * @param id scoped id of the resource * @param scope scope in which this resource is defined - * @param props access short lived certificate properties - * @see [CDKTF Access Short Lived Certificate Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessShortLivedCertificate.typescript.md} + * @param props access short lived certificate properties + * @see [Pulumi Cloudflare Access Short Lived Certificate]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccessshortlivedcertificate/} */ public createAccessShortLivedCertificate( id: string, @@ -86,21 +71,14 @@ export class CloudflareAccessManager { const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessShortLivedCertificate = new ZeroTrustAccessShortLivedCertificate(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessShortLivedCertificate(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput( - `${id}-accessShortLivedCertificateFriendlyUniqueId`, - scope, - accessShortLivedCertificate.friendlyUniqueId - ) - createCloudflareTfOutput(`${id}-accessShortLivedCertificateId`, scope, accessShortLivedCertificate.id) - - return accessShortLivedCertificate } /** @@ -108,21 +86,16 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access custom page properties - * @see [CDKTF Access Custom Page Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessCustomPage.typescript.md} + * @see [Pulumi Cloudflare Access Custom Page]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccesscustompage/} */ public createAccessCustomPage(id: string, scope: CommonCloudflareConstruct, props: ZeroTrustAccessCustomPageProps) { if (!props) throw `Props undefined for ${id}` - const accessCustomPage = new ZeroTrustAccessCustomPage(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessCustomPage(`${id}`, { ...props, accountId: props.accountId ?? scope.props.accountId, name: `${props.name}-${scope.props.stage}`, }) - - createCloudflareTfOutput(`${id}-accessCustomPageFriendlyUniqueId`, scope, accessCustomPage.friendlyUniqueId) - createCloudflareTfOutput(`${id}-accessCustomPageId`, scope, accessCustomPage.id) - - return accessCustomPage } /** @@ -130,25 +103,22 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access group properties - * @see [CDKTF Access Group Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessGroup.typescript.md} + * @see [Pulumi Cloudflare Access Group]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccessgroup/} */ public createAccessGroup(id: string, scope: CommonCloudflareConstruct, props: ZeroTrustAccessGroupProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessGroup = new ZeroTrustAccessGroup(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessGroup(`${id}`, { ...props, name: `${props.name} - ${scope.props.stage.toUpperCase()}`, zoneId, }) - - createCloudflareTfOutput(`${id}-accessGroupFriendlyUniqueId`, scope, accessGroup.friendlyUniqueId) - createCloudflareTfOutput(`${id}-accessGroupId`, scope, accessGroup.id) - - return accessGroup } /** @@ -156,7 +126,7 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access identity provider properties - * @see [CDKTF Access Identity Provider Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessIdentityProvider.typescript.md} + * @see [Pulumi Cloudflare Access Identity Provider]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccessidentityprovider/} */ public createAccessIdentityProvider( id: string, @@ -167,22 +137,16 @@ export class CloudflareAccessManager { const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessIdentityProvider = new ZeroTrustAccessIdentityProvider(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessIdentityProvider(`${id}`, { ...props, + config: props.config ?? {}, name: `${props.name}-${scope.props.stage}`, zoneId, }) - - createCloudflareTfOutput( - `${id}-accessIdentityProviderFriendlyUniqueId`, - scope, - accessIdentityProvider.friendlyUniqueId - ) - createCloudflareTfOutput(`${id}-accessIdentityProviderId`, scope, accessIdentityProvider.id) - - return accessIdentityProvider } /** @@ -190,7 +154,7 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access mutual tls certificate properties - * @see [CDKTF Access Mutual Tls Certificate Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessMtlsCertificate.typescript.md} + * @see [Pulumi Cloudflare Access Mutual Tls Certificate]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccessmtlscertificate/} */ public createAccessMutualTlsCertificate( id: string, @@ -201,22 +165,15 @@ export class CloudflareAccessManager { const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessMutualTlsCertificate = new ZeroTrustAccessMtlsCertificate(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessMtlsCertificate(`${id}`, { ...props, name: `${props.name}-${scope.props.stage}`, zoneId, }) - - createCloudflareTfOutput( - `${id}-accessMutualTlsCertificateFriendlyUniqueId`, - scope, - accessMutualTlsCertificate.friendlyUniqueId - ) - createCloudflareTfOutput(`${id}-accessMutualTlsCertificateId`, scope, accessMutualTlsCertificate.id) - - return accessMutualTlsCertificate } /** @@ -224,24 +181,22 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access organisation properties - * @see [CDKTF Access Organisation Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessOrganization.typescript.md} + * @see [Pulumi Cloudflare Zero Trust Organization]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustorganization/} */ public createAccessOrganization(id: string, scope: CommonCloudflareConstruct, props: ZeroTrustOrganizationProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessOrganization = new ZeroTrustOrganization(scope, `${id}`, { + return new cloudflare.ZeroTrustOrganization(`${id}`, { ...props, name: `${props.name}-${scope.props.stage}`, zoneId, }) - - createCloudflareTfOutput(`${id}-accessOrganizationFriendlyUniqueId`, scope, accessOrganization.friendlyUniqueId) - - return accessOrganization } /** @@ -249,21 +204,16 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access policy properties - * @see [CDKTF Access Policy Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessPolicy.typescript.md} + * @see [Pulumi Cloudflare Access Policy]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccesspolicy/} */ public createAccessPolicy(id: string, scope: CommonCloudflareConstruct, props: ZeroTrustAccessPolicyProps) { if (!props) throw `Props undefined for ${id}` - const accessPolicy = new ZeroTrustAccessPolicy(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessPolicy(`${id}`, { ...props, name: `${props.name}-${scope.props.stage}`, accountId: props.accountId ?? scope.props.accountId, }) - - createCloudflareTfOutput(`${id}-accessPolicyFriendlyUniqueId`, scope, accessPolicy.friendlyUniqueId) - createCloudflareTfOutput(`${id}-accessPolicyId`, scope, accessPolicy.id) - - return accessPolicy } /** @@ -271,25 +221,22 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access rule properties - * @see [CDKTF Access Rule Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/accessRule.typescript.md} + * @see [Pulumi Cloudflare Access Rule]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/accessrule/} */ public createAccessRule(id: string, scope: CommonCloudflareConstruct, props: AccessRuleProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessRule = new AccessRule(scope, `${id}`, { + return new cloudflare.AccessRule(`${id}`, { ...props, zoneId, accountId: props.accountId ?? scope.props.accountId, }) - - createCloudflareTfOutput(`${id}-accessRuleFriendlyUniqueId`, scope, accessRule.friendlyUniqueId) - createCloudflareTfOutput(`${id}-accessRuleId`, scope, accessRule.id) - - return accessRule } /** @@ -297,7 +244,7 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access service token properties - * @see [CDKTF Access Service Token Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessServiceToken.typescript.md} + * @see [Pulumi Cloudflare Access Service Token]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccessservicetoken/} */ public createAccessServiceToken( id: string, @@ -308,19 +255,16 @@ export class CloudflareAccessManager { const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { + filter: { name: scope.props.domainName }, + })?.id - const accessServiceToken = new ZeroTrustAccessServiceToken(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessServiceToken(`${id}`, { ...props, name: `${props.name}-${scope.props.stage}`, accountId: props.accountId ?? scope.props.accountId, zoneId, }) - - createCloudflareTfOutput(`${id}-accessServiceTokenFriendlyUniqueId`, scope, accessServiceToken.friendlyUniqueId) - createCloudflareTfOutput(`${id}-accessServiceTokenId`, scope, accessServiceToken.id) - - return accessServiceToken } /** @@ -328,20 +272,15 @@ export class CloudflareAccessManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props access tag properties - * @see [CDKTF Access Tag Token Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zeroTrustAccessTag.typescript.md} + * @see [Pulumi Cloudflare Access Tag]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/zerotrustaccesstag/} */ public createAccessTag(id: string, scope: CommonCloudflareConstruct, props: ZeroTrustAccessTagProps) { if (!props) throw `Props undefined for ${id}` - const accessTag = new ZeroTrustAccessTag(scope, `${id}`, { + return new cloudflare.ZeroTrustAccessTag(`${id}`, { ...props, name: `${props.name}-${scope.props.stage}`, accountId: props.accountId ?? scope.props.accountId, }) - - createCloudflareTfOutput(`${id}-accessTagFriendlyUniqueId`, scope, accessTag.friendlyUniqueId) - createCloudflareTfOutput(`${id}-accessTagId`, scope, accessTag.id) - - return accessTag } } diff --git a/src/lib/cloudflare/services/access/types.ts b/src/lib/cloudflare/services/access/types.ts index 29f82b8f..9a647d27 100644 --- a/src/lib/cloudflare/services/access/types.ts +++ b/src/lib/cloudflare/services/access/types.ts @@ -1,23 +1,25 @@ -import { AccessRuleConfig } from '@cdktf/provider-cloudflare/lib/access-rule/index.js' -import { ZeroTrustAccessApplicationConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-application/index.js' -import { ZeroTrustAccessCustomPageConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-custom-page/index.js' -import { ZeroTrustAccessGroupConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-group/index.js' -import { ZeroTrustAccessIdentityProviderConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-identity-provider/index.js' -import { ZeroTrustAccessMtlsCertificateConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-mtls-certificate/index.js' -import { ZeroTrustAccessPolicyConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-policy/index.js' -import { ZeroTrustAccessServiceTokenConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-service-token/index.js' -import { ZeroTrustAccessShortLivedCertificateConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-short-lived-certificate/index.js' -import { ZeroTrustAccessTagConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-access-tag/index.js' -import { ZeroTrustOrganizationConfig } from '@cdktf/provider-cloudflare/lib/zero-trust-organization/index.js' +import { + AccessRuleArgs, + ZeroTrustAccessApplicationArgs, + ZeroTrustAccessCustomPageArgs, + ZeroTrustAccessGroupArgs, + ZeroTrustAccessIdentityProviderArgs, + ZeroTrustAccessMtlsCertificateArgs, + ZeroTrustAccessPolicyArgs, + ZeroTrustAccessServiceTokenArgs, + ZeroTrustAccessShortLivedCertificateArgs, + ZeroTrustAccessTagArgs, + ZeroTrustOrganizationArgs, +} from '@pulumi/cloudflare' -export interface ZeroTrustAccessApplicationProps extends ZeroTrustAccessApplicationConfig {} -export interface ZeroTrustAccessShortLivedCertificateProps extends ZeroTrustAccessShortLivedCertificateConfig {} -export interface ZeroTrustAccessCustomPageProps extends ZeroTrustAccessCustomPageConfig {} -export interface ZeroTrustAccessGroupProps extends ZeroTrustAccessGroupConfig {} -export interface ZeroTrustAccessIdentityProviderProps extends ZeroTrustAccessIdentityProviderConfig {} -export interface ZeroTrustAccessMtlsCertificateProps extends ZeroTrustAccessMtlsCertificateConfig {} -export interface ZeroTrustOrganizationProps extends ZeroTrustOrganizationConfig {} -export interface ZeroTrustAccessPolicyProps extends ZeroTrustAccessPolicyConfig {} -export interface AccessRuleProps extends AccessRuleConfig {} -export interface ZeroTrustAccessServiceTokenProps extends ZeroTrustAccessServiceTokenConfig {} -export interface ZeroTrustAccessTagProps extends ZeroTrustAccessTagConfig {} +export interface ZeroTrustAccessApplicationProps extends ZeroTrustAccessApplicationArgs {} +export interface ZeroTrustAccessShortLivedCertificateProps extends ZeroTrustAccessShortLivedCertificateArgs {} +export interface ZeroTrustAccessCustomPageProps extends ZeroTrustAccessCustomPageArgs {} +export interface ZeroTrustAccessGroupProps extends ZeroTrustAccessGroupArgs {} +export interface ZeroTrustAccessIdentityProviderProps extends ZeroTrustAccessIdentityProviderArgs {} +export interface ZeroTrustAccessMtlsCertificateProps extends ZeroTrustAccessMtlsCertificateArgs {} +export interface ZeroTrustOrganizationProps extends ZeroTrustOrganizationArgs {} +export interface ZeroTrustAccessPolicyProps extends ZeroTrustAccessPolicyArgs {} +export interface AccessRuleProps extends AccessRuleArgs {} +export interface ZeroTrustAccessServiceTokenProps extends ZeroTrustAccessServiceTokenArgs {} +export interface ZeroTrustAccessTagProps extends ZeroTrustAccessTagArgs {} diff --git a/src/lib/cloudflare/services/api-shield/main.ts b/src/lib/cloudflare/services/api-shield/main.ts index 0185b821..02af1129 100644 --- a/src/lib/cloudflare/services/api-shield/main.ts +++ b/src/lib/cloudflare/services/api-shield/main.ts @@ -1,10 +1,5 @@ -import { ApiShieldOperationSchemaValidationSettings } from '@cdktf/provider-cloudflare/lib/api-shield-operation-schema-validation-settings/index.js' -import { ApiShieldOperation } from '@cdktf/provider-cloudflare/lib/api-shield-operation/index.js' -import { ApiShieldSchemaValidationSettings } from '@cdktf/provider-cloudflare/lib/api-shield-schema-validation-settings/index.js' -import { ApiShieldSchema } from '@cdktf/provider-cloudflare/lib/api-shield-schema/index.js' -import { ApiShield } from '@cdktf/provider-cloudflare/lib/api-shield/index.js' +import * as cloudflare from '@pulumi/cloudflare' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { ApiShieldOperationProps, ApiShieldOperationSchemaValidationSettingsProps, @@ -36,24 +31,18 @@ export class CloudflareApiShieldManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props api shield properties - * @see [CDKTF API Shield Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/apiShield.typescript.md} + * @see [Pulumi API Shield]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/apishield/} */ public createApiShield(id: string, scope: CommonCloudflareConstruct, props: ApiShieldProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const apiShield = new ApiShield(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.ApiShield(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-apiShieldFriendlyUniqueId`, scope, apiShield.friendlyUniqueId) - createCloudflareTfOutput(`${id}-apiShieldId`, scope, apiShield.id) - - return apiShield } /** @@ -61,25 +50,19 @@ export class CloudflareApiShieldManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props api shield schema properties - * @see [CDKTF API Shield Schema Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/apiShieldSchema.typescript.md} + * @see [Pulumi API Shield Schema]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/apishieldschema/} */ public createApiShieldSchema(id: string, scope: CommonCloudflareConstruct, props: ApiShieldSchemaProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const apiShieldSchema = new ApiShieldSchema(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.ApiShieldSchema(`${id}`, { ...props, name: `${props.name}-${scope.props.stage}`, zoneId, }) - - createCloudflareTfOutput(`${id}-apiShieldSchemaFriendlyUniqueId`, scope, apiShieldSchema.friendlyUniqueId) - createCloudflareTfOutput(`${id}-apiShieldSchemaId`, scope, apiShieldSchema.schemaId) - - return apiShieldSchema } /** @@ -87,7 +70,7 @@ export class CloudflareApiShieldManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props api shield schema validation settings properties - * @see [CDKTF API Shield Schema Validation Settings Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/apiShieldSchema.typescript.md} + * @see [Pulumi API Shield Schema Validation Settings]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/apishieldschemavalidationsettings/} */ public createApiShieldSchemaValidationSettings( id: string, @@ -98,21 +81,11 @@ export class CloudflareApiShieldManager { const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const apiShieldSchemaValidationSettings = new ApiShieldSchemaValidationSettings(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.ApiShieldSchemaValidationSettings(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput( - `${id}-apiShieldSchemaValidationSettingsFriendlyUniqueId`, - scope, - apiShieldSchemaValidationSettings.friendlyUniqueId - ) - createCloudflareTfOutput(`${id}-apiShieldSchemaValidationSettingsId`, scope, apiShieldSchemaValidationSettings.id) - - return apiShieldSchemaValidationSettings } /** @@ -120,24 +93,18 @@ export class CloudflareApiShieldManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props api shield operation properties - * @see [CDKTF API Shield Operation Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/apiShieldOperation.typescript.md} + * @see [Pulumi API Shield Operation]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/apishieldoperation/} */ public createApiShieldOperation(id: string, scope: CommonCloudflareConstruct, props: ApiShieldOperationProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const apiShieldOperation = new ApiShieldOperation(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.ApiShieldOperation(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-apiShieldOperationFriendlyUniqueId`, scope, apiShieldOperation.friendlyUniqueId) - createCloudflareTfOutput(`${id}-apiShieldOperationId`, scope, apiShieldOperation.id) - - return apiShieldOperation } /** @@ -145,7 +112,7 @@ export class CloudflareApiShieldManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props api shield operation schema validation settings properties - * @see [CDKTF API Shield Operation Schema Validation Settings Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/apiShieldOperationSchemaValidationSettings.typescript.md} + * @see [Pulumi API Shield Operation Schema Validation Settings]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/apishieldoperationschemavalidationsettings/} */ public createApiShieldOperationSchemaValidationSettings( id: string, @@ -156,24 +123,10 @@ export class CloudflareApiShieldManager { const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const apiShieldOperationSchemaValidationSettings = new ApiShieldOperationSchemaValidationSettings(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.ApiShieldOperationSchemaValidationSettings(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput( - `${id}-apiShieldOperationSchemaValidationSettingsFriendlyUniqueId`, - scope, - apiShieldOperationSchemaValidationSettings.friendlyUniqueId - ) - createCloudflareTfOutput( - `${id}-apiShieldOperationSchemaValidationSettingsId`, - scope, - apiShieldOperationSchemaValidationSettings.id - ) - - return apiShieldOperationSchemaValidationSettings } } diff --git a/src/lib/cloudflare/services/api-shield/types.ts b/src/lib/cloudflare/services/api-shield/types.ts index 106d2822..b61e6c62 100644 --- a/src/lib/cloudflare/services/api-shield/types.ts +++ b/src/lib/cloudflare/services/api-shield/types.ts @@ -1,11 +1,13 @@ -import { ApiShieldConfig } from '@cdktf/provider-cloudflare/lib/api-shield/index.js' -import { ApiShieldOperationConfig } from '@cdktf/provider-cloudflare/lib/api-shield-operation/index.js' -import { ApiShieldOperationSchemaValidationSettingsConfig } from '@cdktf/provider-cloudflare/lib/api-shield-operation-schema-validation-settings/index.js' -import { ApiShieldSchemaConfig } from '@cdktf/provider-cloudflare/lib/api-shield-schema/index.js' -import { ApiShieldSchemaValidationSettingsConfig } from '@cdktf/provider-cloudflare/lib/api-shield-schema-validation-settings/index.js' +import { + ApiShieldArgs, + ApiShieldOperationArgs, + ApiShieldOperationSchemaValidationSettingsArgs, + ApiShieldSchemaArgs, + ApiShieldSchemaValidationSettingsArgs, +} from '@pulumi/cloudflare' -export interface ApiShieldProps extends ApiShieldConfig {} -export interface ApiShieldSchemaProps extends ApiShieldSchemaConfig {} -export interface ApiShieldSchemaValidationSettingsProps extends ApiShieldSchemaValidationSettingsConfig {} -export interface ApiShieldOperationProps extends ApiShieldOperationConfig {} -export interface ApiShieldOperationSchemaValidationSettingsProps extends ApiShieldOperationSchemaValidationSettingsConfig {} +export interface ApiShieldProps extends ApiShieldArgs {} +export interface ApiShieldSchemaProps extends ApiShieldSchemaArgs {} +export interface ApiShieldSchemaValidationSettingsProps extends ApiShieldSchemaValidationSettingsArgs {} +export interface ApiShieldOperationProps extends ApiShieldOperationArgs {} +export interface ApiShieldOperationSchemaValidationSettingsProps extends ApiShieldOperationSchemaValidationSettingsArgs {} diff --git a/src/lib/cloudflare/services/argo/main.ts b/src/lib/cloudflare/services/argo/main.ts index a8809849..69713e99 100644 --- a/src/lib/cloudflare/services/argo/main.ts +++ b/src/lib/cloudflare/services/argo/main.ts @@ -1,7 +1,5 @@ -import { ArgoSmartRouting } from '@cdktf/provider-cloudflare/lib/argo-smart-routing/index.js' -import { ArgoTieredCaching } from '@cdktf/provider-cloudflare/lib/argo-tiered-caching/index.js' +import * as cloudflare from '@pulumi/cloudflare' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { ArgoSmartRoutingProps, ArgoTieredCachingProps } from './types.js' /** @@ -23,52 +21,40 @@ import { ArgoSmartRoutingProps, ArgoTieredCachingProps } from './types.js' */ export class CloudflareArgoManager { /** - * @summary Method to create a new Cloudflare Argo + * @summary Method to create a new Cloudflare Argo Smart Routing * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props argo properties - * @see [CDKTF Argo Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/argoSmartRouting.typescript.md} + * @see [Pulumi Cloudflare ArgoSmartRouting]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/argosmartrouting/} */ public createArgoSmartRouting(id: string, scope: CommonCloudflareConstruct, props: ArgoSmartRoutingProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const argoSmartRouting = new ArgoSmartRouting(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.ArgoSmartRouting(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-argoSmartRoutingFriendlyUniqueId`, scope, argoSmartRouting.friendlyUniqueId) - createCloudflareTfOutput(`${id}-argoSmartRoutingId`, scope, argoSmartRouting.id) - - return argoSmartRouting } /** - * @summary Method to create a new Cloudflare Argo + * @summary Method to create a new Cloudflare Argo Tiered Caching * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props argo properties - * @see [CDKTF Argo Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/argoTieredCaching.typescript.md} + * @see [Pulumi Cloudflare ArgoTieredCaching]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/argotieredcaching/} */ public createArgoTieredCaching(id: string, scope: CommonCloudflareConstruct, props: ArgoTieredCachingProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const argoTieredCaching = new ArgoTieredCaching(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.ArgoTieredCaching(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-argoTieredCachingFriendlyUniqueId`, scope, argoTieredCaching.friendlyUniqueId) - createCloudflareTfOutput(`${id}-argoTieredCachingId`, scope, argoTieredCaching.id) - - return argoTieredCaching } } diff --git a/src/lib/cloudflare/services/argo/types.ts b/src/lib/cloudflare/services/argo/types.ts index 983a6e96..957a1fa2 100644 --- a/src/lib/cloudflare/services/argo/types.ts +++ b/src/lib/cloudflare/services/argo/types.ts @@ -1,5 +1,4 @@ -import { ArgoSmartRoutingConfig } from '@cdktf/provider-cloudflare/lib/argo-smart-routing/index.js' -import { ArgoTieredCachingConfig } from '@cdktf/provider-cloudflare/lib/argo-tiered-caching/index.js' +import { ArgoSmartRoutingArgs, ArgoTieredCachingArgs } from '@pulumi/cloudflare' -export interface ArgoSmartRoutingProps extends ArgoSmartRoutingConfig {} -export interface ArgoTieredCachingProps extends ArgoTieredCachingConfig {} +export interface ArgoSmartRoutingProps extends ArgoSmartRoutingArgs {} +export interface ArgoTieredCachingProps extends ArgoTieredCachingArgs {} diff --git a/src/lib/cloudflare/services/filter/main.ts b/src/lib/cloudflare/services/filter/main.ts index ab61e86a..8fcaa226 100644 --- a/src/lib/cloudflare/services/filter/main.ts +++ b/src/lib/cloudflare/services/filter/main.ts @@ -1,6 +1,5 @@ -import { Filter } from '@cdktf/provider-cloudflare/lib/filter/index.js' +import * as cloudflare from '@pulumi/cloudflare' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { FilterProps } from './types.js' /** @@ -26,23 +25,17 @@ export class CloudflareFilterManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props filter properties - * @see [CDKTF Filter Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/filter.typescript.md} + * @see [Pulumi Cloudflare Filter]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/filter/} */ public createApiShield(id: string, scope: CommonCloudflareConstruct, props: FilterProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const filter = new Filter(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.Filter(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-filterFriendlyUniqueId`, scope, filter.friendlyUniqueId) - createCloudflareTfOutput(`${id}-filterId`, scope, filter.id) - - return filter } } diff --git a/src/lib/cloudflare/services/filter/types.ts b/src/lib/cloudflare/services/filter/types.ts index a74f2663..3aa990ab 100644 --- a/src/lib/cloudflare/services/filter/types.ts +++ b/src/lib/cloudflare/services/filter/types.ts @@ -1,3 +1,3 @@ -import { FilterConfig } from '@cdktf/provider-cloudflare/lib/filter/index.js' +import { FilterArgs } from '@pulumi/cloudflare' -export interface FilterProps extends FilterConfig {} +export interface FilterProps extends FilterArgs {} diff --git a/src/lib/cloudflare/services/firewall/main.ts b/src/lib/cloudflare/services/firewall/main.ts index bf2052d8..b58d0642 100644 --- a/src/lib/cloudflare/services/firewall/main.ts +++ b/src/lib/cloudflare/services/firewall/main.ts @@ -1,6 +1,5 @@ -import { FirewallRule } from '@cdktf/provider-cloudflare/lib/firewall-rule/index.js' +import * as cloudflare from '@pulumi/cloudflare' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { FirewallRuleProps } from './types.js' /** @@ -26,23 +25,17 @@ export class CloudflareFirewallManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props firewall rule properties - * @see [CDKTF Firewall Rule Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/firewallRule.typescript.md} + * @see [Pulumi Cloudflare Firewall Rule]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/firewallrule/} */ public createFirewallRule(id: string, scope: CommonCloudflareConstruct, props: FirewallRuleProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const firewallRule = new FirewallRule(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.FirewallRule(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-firewallRuleFriendlyUniqueId`, scope, firewallRule.friendlyUniqueId) - createCloudflareTfOutput(`${id}-firewallRuleId`, scope, firewallRule.id) - - return firewallRule } } diff --git a/src/lib/cloudflare/services/firewall/types.ts b/src/lib/cloudflare/services/firewall/types.ts index d650981f..1bcec267 100644 --- a/src/lib/cloudflare/services/firewall/types.ts +++ b/src/lib/cloudflare/services/firewall/types.ts @@ -1,3 +1,3 @@ -import { FirewallRuleConfig } from '@cdktf/provider-cloudflare/lib/firewall-rule/index.js' +import { FirewallRuleArgs } from '@pulumi/cloudflare' -export interface FirewallRuleProps extends FirewallRuleConfig {} +export interface FirewallRuleProps extends FirewallRuleArgs {} diff --git a/src/lib/cloudflare/services/page/main.ts b/src/lib/cloudflare/services/page/main.ts index ac5862e7..1a4d062a 100644 --- a/src/lib/cloudflare/services/page/main.ts +++ b/src/lib/cloudflare/services/page/main.ts @@ -1,9 +1,6 @@ -import { PageRule } from '@cdktf/provider-cloudflare/lib/page-rule/index.js' -import { PagesDomain } from '@cdktf/provider-cloudflare/lib/pages-domain/index.js' -import { PagesProject } from '@cdktf/provider-cloudflare/lib/pages-project/index.js' -import { LocalExec, Provider } from 'cdktf-local-exec' +import * as cloudflare from '@pulumi/cloudflare' +import { local } from '@pulumi/command' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { PageRuleProps, PagesDomainProps, PagesProjectDeployProps, PagesProjectProps } from './types.js' /** @@ -29,21 +26,16 @@ export class CloudflarePageManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props pages project properties - * @see [CDKTF Pages Project Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/pagesProject.typescript.md} + * @see [Pulumi Cloudflare Pages Project]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/pagesproject/} */ public createPagesProject(id: string, scope: CommonCloudflareConstruct, props: PagesProjectProps) { if (!props) throw `Props undefined for ${id}` - const pagesProject = new PagesProject(scope, `${id}`, { + return new cloudflare.PagesProject(`${id}`, { ...props, accountId: props.accountId ?? scope.props.accountId, name: `${props.name}-${scope.props.stage}`, }) - - createCloudflareTfOutput(`${id}-pagesProjectFriendlyUniqueId`, scope, pagesProject.friendlyUniqueId) - createCloudflareTfOutput(`${id}-pagesProjectId`, scope, pagesProject.id) - - return pagesProject } /** @@ -51,21 +43,16 @@ export class CloudflarePageManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props pages domain properties - * @see [CDKTF Pages Domain Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/pagesDomain.typescript.md} + * @see [Pulumi Cloudflare Pages Domain]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/pagesdomain/} */ public createPagesDomain(id: string, scope: CommonCloudflareConstruct, props: PagesDomainProps) { if (!props) throw `Props undefined for ${id}` - const pagesDomain = new PagesDomain(scope, `${id}`, { + return new cloudflare.PagesDomain(`${id}`, { ...props, accountId: props.accountId ?? scope.props.accountId, name: props.name ?? scope.props.domainName, }) - - createCloudflareTfOutput(`${id}-pagesDomainFriendlyUniqueId`, scope, pagesDomain.friendlyUniqueId) - createCloudflareTfOutput(`${id}-pagesDomainId`, scope, pagesDomain.id) - - return pagesDomain } /** @@ -73,37 +60,33 @@ export class CloudflarePageManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props page rule properties - * @see [CDKTF Page Rule Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/pageRule.typescript.md} + * @see [Pulumi Cloudflare Page Rule]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/pagerule/} */ public createPageRule(id: string, scope: CommonCloudflareConstruct, props: PageRuleProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const pageRule = new PageRule(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.PageRule(`${id}`, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-pageRuleFriendlyUniqueId`, scope, pageRule.friendlyUniqueId) - createCloudflareTfOutput(`${id}-pageRuleId`, scope, pageRule.id) - - return pageRule } public deployPagesProject(id: string, scope: CommonCloudflareConstruct, props: PagesProjectDeployProps) { if (!props) throw `Props undefined for ${id}` - new Provider(scope, `${id}`) const message = process.env.BUILD_NUMBER ?? props.message - const deployment = new LocalExec(scope, `${id}-deploy-${new Date().toISOString()}`, { - command: `CLOUDFLARE_ACCOUNT_ID=${scope.props.accountId} CLOUDFLARE_API_TOKEN=${scope.props.apiToken} npx wrangler pages deploy ${props.directory} --project-name=${props.projectName} --branch=${props.branch} --commit-message=${message}`, - cwd: '', - dependsOn: props.dependsOn, - }) - - return deployment + return new local.Command( + `${id}-deploy-${new Date().toISOString()}`, + { + create: `CLOUDFLARE_ACCOUNT_ID=${scope.props.accountId} CLOUDFLARE_API_TOKEN=${scope.props.apiToken} npx wrangler pages deploy ${props.directory} --project-name=${props.projectName} --branch=${props.branch} --commit-message=${message}`, + dir: '', + }, + { + dependsOn: props.dependsOn, + } + ) } } diff --git a/src/lib/cloudflare/services/page/types.ts b/src/lib/cloudflare/services/page/types.ts index 0592a128..858e1161 100644 --- a/src/lib/cloudflare/services/page/types.ts +++ b/src/lib/cloudflare/services/page/types.ts @@ -1,10 +1,8 @@ -import { PageRuleConfig } from '@cdktf/provider-cloudflare/lib/page-rule/index.js' -import { PagesDomainConfig } from '@cdktf/provider-cloudflare/lib/pages-domain/index.js' -import { PagesProjectConfig } from '@cdktf/provider-cloudflare/lib/pages-project/index.js' +import { PageRuleArgs, PagesDomainArgs, PagesProjectArgs } from '@pulumi/cloudflare' -export interface PagesProjectProps extends PagesProjectConfig {} -export interface PagesDomainProps extends PagesDomainConfig {} -export interface PageRuleProps extends PageRuleConfig {} +export interface PagesProjectProps extends PagesProjectArgs {} +export interface PagesDomainProps extends PagesDomainArgs {} +export interface PageRuleProps extends PageRuleArgs {} export interface PagesProjectDeployProps { branch: string directory: string diff --git a/src/lib/cloudflare/services/record/main.ts b/src/lib/cloudflare/services/record/main.ts index caa7ba4d..3a3d3ba9 100644 --- a/src/lib/cloudflare/services/record/main.ts +++ b/src/lib/cloudflare/services/record/main.ts @@ -1,6 +1,5 @@ -import { DnsRecord } from '@cdktf/provider-cloudflare/lib/dns-record/index.js' +import * as cloudflare from '@pulumi/cloudflare' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { DnsRecordProps } from './types.js' /** @@ -26,23 +25,17 @@ export class CloudflareRecordManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props record properties - * @see [CDKTF Record Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/dnsRecord.typescript.md} + * @see [Pulumi Cloudflare Record]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/} */ public createRecord(id: string, scope: CommonCloudflareConstruct, props: DnsRecordProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const record = new DnsRecord(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.DnsRecord(id, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-recordFriendlyUniqueId`, scope, record.friendlyUniqueId) - createCloudflareTfOutput(`${id}-recordId`, scope, record.id) - - return record } } diff --git a/src/lib/cloudflare/services/record/types.ts b/src/lib/cloudflare/services/record/types.ts index 765fa01b..571a27c1 100644 --- a/src/lib/cloudflare/services/record/types.ts +++ b/src/lib/cloudflare/services/record/types.ts @@ -1,3 +1,3 @@ -import { DnsRecordConfig } from '@cdktf/provider-cloudflare/lib/dns-record/index.js' +import { DnsRecordArgs } from '@pulumi/cloudflare' -export interface DnsRecordProps extends DnsRecordConfig {} +export interface DnsRecordProps extends DnsRecordArgs {} diff --git a/src/lib/cloudflare/services/rule-set/main.ts b/src/lib/cloudflare/services/rule-set/main.ts index 4bf8b628..fcd59040 100644 --- a/src/lib/cloudflare/services/rule-set/main.ts +++ b/src/lib/cloudflare/services/rule-set/main.ts @@ -1,6 +1,5 @@ -import { Ruleset } from '@cdktf/provider-cloudflare/lib/ruleset/index.js' +import * as cloudflare from '@pulumi/cloudflare' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { RulesetProps } from './types.js' /** @@ -9,11 +8,11 @@ import { RulesetProps } from './types.js' * - If a custom construct extends {@link CommonCloudflareConstruct}, an instance is available within the context. * @example * ``` - * import { CommonCloudflareConstruct, CommonCloudflareConstruct } from '@gradientedge/cdk-utils' + * import { CommonCloudflareConstruct } from '@gradientedge/cdk-utils' * * class CustomConstruct extends CommonCloudflareConstruct { - * constructor(parent: Construct, id: string, props: CommonCloudflareStackProps) { - * super(parent, id, props) + * constructor(parent: pulumi.ComponentResource, name: string, props: CommonCloudflareStackProps) { + * super(parent, name, props) * this.props = props * this.ruleSetManager.createRuleSet('MyRule', this, props) * } @@ -26,23 +25,19 @@ export class CloudflareRuleSetManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props rule set properties - * @see [CDKTF Ruleset Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/ruleset.typescript.md} + * @see [Pulumi Cloudflare Ruleset]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/ruleset/} */ public createRuleSet(id: string, scope: CommonCloudflareConstruct, props: RulesetProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const ruleSet = new Ruleset(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + const ruleSet = new cloudflare.Ruleset(`${id}`, { ...props, zoneId, }) - createCloudflareTfOutput(`${id}-ruleSetFriendlyUniqueId`, scope, ruleSet.friendlyUniqueId) - createCloudflareTfOutput(`${id}-ruleSetId`, scope, ruleSet.id) - return ruleSet } } diff --git a/src/lib/cloudflare/services/rule-set/types.ts b/src/lib/cloudflare/services/rule-set/types.ts index e40171b6..7290e4c4 100644 --- a/src/lib/cloudflare/services/rule-set/types.ts +++ b/src/lib/cloudflare/services/rule-set/types.ts @@ -1,3 +1,3 @@ -import { RulesetConfig } from '@cdktf/provider-cloudflare/lib/ruleset/index.js' +import * as cloudflare from '@pulumi/cloudflare' -export interface RulesetProps extends RulesetConfig {} +export interface RulesetProps extends cloudflare.RulesetArgs {} diff --git a/src/lib/cloudflare/services/worker/main.ts b/src/lib/cloudflare/services/worker/main.ts index 3a93f947..750f481c 100644 --- a/src/lib/cloudflare/services/worker/main.ts +++ b/src/lib/cloudflare/services/worker/main.ts @@ -1,11 +1,5 @@ -import { WorkersCronTrigger } from '@cdktf/provider-cloudflare/lib/workers-cron-trigger/index.js' -import { WorkersCustomDomain } from '@cdktf/provider-cloudflare/lib/workers-custom-domain/index.js' -import { WorkersKvNamespace } from '@cdktf/provider-cloudflare/lib/workers-kv-namespace/index.js' -import { WorkersKv } from '@cdktf/provider-cloudflare/lib/workers-kv/index.js' -import { WorkersRoute } from '@cdktf/provider-cloudflare/lib/workers-route/index.js' -import { WorkersScript } from '@cdktf/provider-cloudflare/lib/workers-script/index.js' +import * as cloudflare from '@pulumi/cloudflare' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { WorkerCronTriggerProps, WorkerDomainProps, @@ -38,25 +32,19 @@ export class CloudflareWorkerManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props worker domain properties - * @see [CDKTF Worker Domain Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/workersCustomDomain.typescript.md} + * @see [Pulumi Worker Domain]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/workercustomdomain/} */ public createWorkerDomain(id: string, scope: CommonCloudflareConstruct, props: WorkerDomainProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId - - const workerDomain = new WorkersCustomDomain(scope, `${id}`, { + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id + return new cloudflare.WorkersCustomDomain(id, { ...props, accountId: props.accountId ?? scope.props.accountId, zoneId, }) - - createCloudflareTfOutput(`${id}-workerDomainFriendlyUniqueId`, scope, workerDomain.friendlyUniqueId) - createCloudflareTfOutput(`${id}-workerDomainId`, scope, workerDomain.id) - - return workerDomain } /** @@ -64,25 +52,20 @@ export class CloudflareWorkerManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props worker route properties - * @see [CDKTF Worker Route Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/workersRoute.typescript.md} + * @see [Pulumi Worker Route]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/workerroute/} */ public createWorkerRoute(id: string, scope: CommonCloudflareConstruct, props: WorkerRouteProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId ? props.zoneId - : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.zoneId + : scope.zoneManager.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })?.id - const workerRoute = new WorkersRoute(scope, `${id}`, { + return new cloudflare.WorkersRoute(id, { ...props, script: `${props.script}-${scope.props.stage}`, zoneId, }) - - createCloudflareTfOutput(`${id}-workerRouteFriendlyUniqueId`, scope, workerRoute.friendlyUniqueId) - createCloudflareTfOutput(`${id}-workerRouteId`, scope, workerRoute.id) - - return workerRoute } /** @@ -90,21 +73,16 @@ export class CloudflareWorkerManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props worker script properties - * @see [CDKTF Worker Script Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/workersScript.typescript.md} + * @see [Pulumi Worker Script]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/workerscript/} */ public createWorkerScript(id: string, scope: CommonCloudflareConstruct, props: WorkerScriptProps) { if (!props) throw `Props undefined for ${id}` - const workerScript = new WorkersScript(scope, `${id}`, { + return new cloudflare.WorkersScript(id, { ...props, accountId: props.accountId ?? scope.props.accountId, scriptName: `${props.scriptName}-${scope.props.stage}`, }) - - createCloudflareTfOutput(`${id}-workerScriptFriendlyUniqueId`, scope, workerScript.friendlyUniqueId) - createCloudflareTfOutput(`${id}-workerScriptId`, scope, workerScript.id) - - return workerScript } /** @@ -112,21 +90,16 @@ export class CloudflareWorkerManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props workers kv namespace properties - * @see [CDKTF Workers KV Namespace Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/workersKvNamespace.typescript.md} + * @see [Pulumi Workers KV Namespace]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/workerskvnamespace/} */ public createWorkersKvNamespace(id: string, scope: CommonCloudflareConstruct, props: WorkersKvNamespaceProps) { if (!props) throw `Props undefined for ${id}` - const workersKvNamespace = new WorkersKvNamespace(scope, `${id}`, { + return new cloudflare.WorkersKvNamespace(id, { ...props, accountId: props.accountId ?? scope.props.accountId, title: scope.isProductionStage() ? props.title : `${props.title}-${scope.props.stage}`, }) - - createCloudflareTfOutput(`${id}-workersKvNamespaceFriendlyUniqueId`, scope, workersKvNamespace.friendlyUniqueId) - createCloudflareTfOutput(`${id}-workersKvNamespaceId`, scope, workersKvNamespace.id) - - return workersKvNamespace } /** @@ -134,20 +107,15 @@ export class CloudflareWorkerManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props workers kv properties - * @see [CDKTF Workers KV Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/workersKv.typescript.md} + * @see [Pulumi Workers KV]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/workerskv/} */ public createWorkersKv(id: string, scope: CommonCloudflareConstruct, props: WorkersKvProps) { if (!props) throw `Props undefined for ${id}` - const workersKv = new WorkersKv(scope, `${id}`, { + return new cloudflare.WorkersKv(id, { ...props, accountId: props.accountId ?? scope.props.accountId, }) - - createCloudflareTfOutput(`${id}-workersKvFriendlyUniqueId`, scope, workersKv.friendlyUniqueId) - createCloudflareTfOutput(`${id}-workersKvId`, scope, workersKv.id) - - return workersKv } /** @@ -155,19 +123,14 @@ export class CloudflareWorkerManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props workers cron trigger properties - * @see [CDKTF Workers Cron Trigger Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/workersCronTrigger.typescript.md} + * @see [Pulumi Workers Cron Trigger]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/workercrontrigger/} */ public createWorkerCronTrigger(id: string, scope: CommonCloudflareConstruct, props: WorkerCronTriggerProps) { if (!props) throw `Props undefined for ${id}` - const workerCronTrigger = new WorkersCronTrigger(scope, `${id}`, { + return new cloudflare.WorkersCronTrigger(id, { ...props, accountId: props.accountId ?? scope.props.accountId, }) - - createCloudflareTfOutput(`${id}-workerCronTriggerFriendlyUniqueId`, scope, workerCronTrigger.friendlyUniqueId) - createCloudflareTfOutput(`${id}-workerCronTriggerId`, scope, workerCronTrigger.id) - - return workerCronTrigger } } diff --git a/src/lib/cloudflare/services/worker/types.ts b/src/lib/cloudflare/services/worker/types.ts index 583ba3c9..59e8be8b 100644 --- a/src/lib/cloudflare/services/worker/types.ts +++ b/src/lib/cloudflare/services/worker/types.ts @@ -1,13 +1,15 @@ -import { WorkersCronTriggerConfig } from '@cdktf/provider-cloudflare/lib/workers-cron-trigger/index.js' -import { WorkersCustomDomainConfig } from '@cdktf/provider-cloudflare/lib/workers-custom-domain/index.js' -import { WorkersRouteConfig } from '@cdktf/provider-cloudflare/lib/workers-route/index.js' -import { WorkersScriptConfig } from '@cdktf/provider-cloudflare/lib/workers-script/index.js' -import { WorkersKvConfig } from '@cdktf/provider-cloudflare/lib/workers-kv/index.js' -import { WorkersKvNamespaceConfig } from '@cdktf/provider-cloudflare/lib/workers-kv-namespace/index.js' +import { + WorkersCronTriggerArgs, + WorkersCustomDomainArgs, + WorkersKvArgs, + WorkersKvNamespaceArgs, + WorkersRouteArgs, + WorkersScriptArgs, +} from '@pulumi/cloudflare' -export interface WorkerDomainProps extends WorkersCustomDomainConfig {} -export interface WorkerRouteProps extends WorkersRouteConfig {} -export interface WorkerScriptProps extends WorkersScriptConfig {} -export interface WorkersKvNamespaceProps extends WorkersKvNamespaceConfig {} -export interface WorkersKvProps extends WorkersKvConfig {} -export interface WorkerCronTriggerProps extends WorkersCronTriggerConfig {} +export interface WorkerDomainProps extends WorkersCustomDomainArgs {} +export interface WorkerRouteProps extends WorkersRouteArgs {} +export interface WorkerScriptProps extends WorkersScriptArgs {} +export interface WorkersKvNamespaceProps extends WorkersKvNamespaceArgs {} +export interface WorkersKvProps extends WorkersKvArgs {} +export interface WorkerCronTriggerProps extends WorkersCronTriggerArgs {} diff --git a/src/lib/cloudflare/services/zone/main.ts b/src/lib/cloudflare/services/zone/main.ts index 6bec3754..7c898d9c 100644 --- a/src/lib/cloudflare/services/zone/main.ts +++ b/src/lib/cloudflare/services/zone/main.ts @@ -1,35 +1,27 @@ -import { DataCloudflareZone } from '@cdktf/provider-cloudflare/lib/data-cloudflare-zone/index.js' -import { ZoneCacheReserve } from '@cdktf/provider-cloudflare/lib/zone-cache-reserve/index.js' -import { ZoneCacheVariants } from '@cdktf/provider-cloudflare/lib/zone-cache-variants/index.js' -import { ZoneDnsSettings } from '@cdktf/provider-cloudflare/lib/zone-dns-settings/index.js' -import { ZoneDnssec } from '@cdktf/provider-cloudflare/lib/zone-dnssec/index.js' -import { ZoneHold } from '@cdktf/provider-cloudflare/lib/zone-hold/index.js' -import { ZoneLockdown } from '@cdktf/provider-cloudflare/lib/zone-lockdown/index.js' -import { ZoneSetting } from '@cdktf/provider-cloudflare/lib/zone-setting/index.js' -import { Zone } from '@cdktf/provider-cloudflare/lib/zone/index.js' +import * as cloudflare from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' import { CommonCloudflareConstruct } from '../../common/index.js' -import { createCloudflareTfOutput } from '../../utils/index.js' import { + GetZoneProps, ZoneCacheReserveProps, ZoneCacheVariantsProps, ZoneDnssecProps, ZoneHoldProps, ZoneLockdownProps, - ZoneOptions, ZoneProps, ZoneSettingProps, } from './types.js' /** - * @classdesc Provides operations on Cloudflare Zone + * @classdesc Provides operations on Cloudflare Zone using Pulumi * - A new instance of this class is injected into {@link CommonCloudflareConstruct} constructor. * - If a custom construct extends {@link CommonCloudflareConstruct}, an instance is available within the context. * @example * ``` - * import { CommonCloudflareConstruct, CommonCloudflareConstruct } from '@gradientedge/cdk-utils' + * import { CommonCloudflareConstruct } from '@gradientedge/cdk-utils' * * class CustomConstruct extends CommonCloudflareConstruct { - * constructor(parent: Construct, id: string, props: CommonCloudflareStackProps) { + * constructor(parent: pulumi.ComponentResource, id: string, props: CommonCloudflareStackProps) { * super(parent, id, props) * this.props = props * this.zoneManager.createZone('MyZone', this, props) @@ -43,35 +35,20 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone properties - * @see [CDKTF Zone Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zone.typescript.md} */ public createZone(id: string, scope: CommonCloudflareConstruct, props: ZoneProps) { if (!props) throw `Props undefined for ${id}` - const zone = new Zone(scope, `${id}`, { + return new cloudflare.Zone(id, { ...props, - account: { - id: props.account.id ?? scope.props.accountId, - }, - name: props.name ?? scope.props.domainName, + account: props.account ?? scope.props.accountId, + name: scope.props.domainName, }) - - createCloudflareTfOutput(`${id}-zoneName`, scope, zone.name) - createCloudflareTfOutput(`${id}-zoneFriendlyUniqueId`, scope, zone.friendlyUniqueId) - createCloudflareTfOutput(`${id}-zoneId`, scope, zone.id) - - return zone } - public resolveZone(id: string, scope: CommonCloudflareConstruct, options?: ZoneOptions) { - const zone = new DataCloudflareZone(scope, `${id}-data-zone`, { - filter: { - name: options?.name ?? scope.props.domainName, - }, - zoneId: options?.zoneId, - }) - - return zone + public resolveZone(id: string, scope: CommonCloudflareConstruct, options?: GetZoneProps) { + const name = options?.filter?.name ?? scope.props.domainName + return cloudflare.Zone.get(name, id) } /** @@ -79,24 +56,17 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone cache reserve properties - * @see [CDKTF Zone Cache Reserve Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zoneCacheReserve.typescript.md} */ public createZoneCacheReserve(id: string, scope: CommonCloudflareConstruct, props: ZoneCacheReserveProps) { if (!props) throw `Props undefined for ${id}` - const zoneId = props.zoneId - ? props.zoneId - : this.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.id - - const zoneCacheReserve = new ZoneCacheReserve(scope, `${id}`, { + const zoneId = + props.zoneId ?? + pulumi.output(this.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })).id + return new cloudflare.ZoneCacheReserve(id, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-zoneCacheReserveFriendlyUniqueId`, scope, zoneCacheReserve.friendlyUniqueId) - createCloudflareTfOutput(`${id}-zoneCacheReserveId`, scope, zoneCacheReserve.id) - - return zoneCacheReserve } /** @@ -104,23 +74,17 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone cache variants properties - * @see [CDKTF Zone Cache Variants Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zoneCacheVariants.typescript.md} */ public createZoneCacheVariants(id: string, scope: CommonCloudflareConstruct, props: ZoneCacheVariantsProps) { if (!props) throw `Props undefined for ${id}` - const zoneId = props.zoneId - ? props.zoneId - : this.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.id - const zoneCacheVariants = new ZoneCacheVariants(scope, `${id}`, { + const zoneId = + props.zoneId ?? + pulumi.output(this.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })).id + return new cloudflare.ZoneCacheVariants(id, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-zoneCacheVariantsFriendlyUniqueId`, scope, zoneCacheVariants.friendlyUniqueId) - createCloudflareTfOutput(`${id}-zoneCacheVariantsId`, scope, zoneCacheVariants.id) - - return zoneCacheVariants } /** @@ -128,23 +92,17 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone dnssec properties - * @see [CDKTF Zone DNS Security Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zoneDnssec.typescript.md} */ public createZoneDnssec(id: string, scope: CommonCloudflareConstruct, props: ZoneDnssecProps) { if (!props) throw `Props undefined for ${id}` - const zoneId = props.zoneId - ? props.zoneId - : this.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.id - const zoneDnssec = new ZoneDnssec(scope, `${id}`, { + const zoneId = + props.zoneId ?? + pulumi.output(this.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })).id + return new cloudflare.ZoneDnssec(id, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-zoneDnssecFriendlyUniqueId`, scope, zoneDnssec.friendlyUniqueId) - createCloudflareTfOutput(`${id}-zoneDnssecId`, scope, zoneDnssec.id) - - return zoneDnssec } /** @@ -152,23 +110,17 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone hold properties - * @see [CDKTF Zone Hold Security Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zoneHold.typescript.md} */ public createZoneHold(id: string, scope: CommonCloudflareConstruct, props: ZoneHoldProps) { if (!props) throw `Props undefined for ${id}` - const zoneId = props.zoneId - ? props.zoneId - : this.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.id - const zoneHold = new ZoneHold(scope, `${id}`, { + const zoneId = + props.zoneId ?? + pulumi.output(this.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })).id + return new cloudflare.ZoneHold(id, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-zoneHoldFriendlyUniqueId`, scope, zoneHold.friendlyUniqueId) - createCloudflareTfOutput(`${id}-zoneHoldId`, scope, zoneHold.id) - - return zoneHold } /** @@ -176,23 +128,17 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone lockdown properties - * @see [CDKTF Zone Lockdown Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zoneLockdown.typescript.md} */ public createZoneLockdown(id: string, scope: CommonCloudflareConstruct, props: ZoneLockdownProps) { if (!props) throw `Props undefined for ${id}` - const zoneId = props.zoneId - ? props.zoneId - : this.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.id - const zoneLockdown = new ZoneLockdown(scope, `${id}`, { + const zoneId = + props.zoneId ?? + pulumi.output(this.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })).id + return new cloudflare.ZoneLockdown(id, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-zoneLockdownFriendlyUniqueId`, scope, zoneLockdown.friendlyUniqueId) - createCloudflareTfOutput(`${id}-zoneLockdownId`, scope, zoneLockdown.id) - - return zoneLockdown } /** @@ -200,21 +146,18 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone dns settings properties - * @see [CDKTF Zone Dns Settings Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/dnsZoneSettings.typescript.md} */ public createZoneDnsSettings(id: string, scope: CommonCloudflareConstruct, props: ZoneSettingProps) { if (!props) throw `Props undefined for ${id}` - const zoneId = props.zoneId - ? props.zoneId - : this.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.id - const zoneDnsSettings = new ZoneDnsSettings(scope, `${id}`, { + const zoneId = + props.zoneId ?? + pulumi.output(this.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })).id + const zoneDnsSettings = new cloudflare.ZoneSetting(id, { ...props, zoneId, }) - createCloudflareTfOutput(`${id}-zoneDnsSettingsFriendlyUniqueId`, scope, zoneDnsSettings.friendlyUniqueId) - return zoneDnsSettings } @@ -223,22 +166,16 @@ export class CloudflareZoneManager { * @param id scoped id of the resource * @param scope scope in which this resource is defined * @param props zone setting properties - * @see [CDKTF Zone Setting Module]{@link https://github.com/cdktf/cdktf-provider-cloudflare/blob/main/docs/zoneSetting.typescript.md} */ public createZoneSetting(id: string, scope: CommonCloudflareConstruct, props: ZoneSettingProps) { if (!props) throw `Props undefined for ${id}` - const zoneId = props.zoneId - ? props.zoneId - : this.resolveZone(`${id}-data-zone`, scope, { name: scope.props.domainName })?.id - const zoneSetting = new ZoneSetting(scope, `${id}`, { + const zoneId = + props.zoneId ?? + pulumi.output(this.resolveZone(`${id}-data-zone`, scope, { filter: { name: scope.props.domainName } })).id + return new cloudflare.ZoneSetting(id, { ...props, zoneId, }) - - createCloudflareTfOutput(`${id}-zoneSettingFriendlyUniqueId`, scope, zoneSetting.friendlyUniqueId) - createCloudflareTfOutput(`${id}-zoneSettingId`, scope, zoneSetting.id) - - return zoneSetting } } diff --git a/src/lib/cloudflare/services/zone/types.ts b/src/lib/cloudflare/services/zone/types.ts index af59d323..9cdda52c 100644 --- a/src/lib/cloudflare/services/zone/types.ts +++ b/src/lib/cloudflare/services/zone/types.ts @@ -1,22 +1,21 @@ -import { ZoneConfig } from '@cdktf/provider-cloudflare/lib/zone/index.js' -import { ZoneCacheReserveConfig } from '@cdktf/provider-cloudflare/lib/zone-cache-reserve/index.js' -import { ZoneCacheVariantsConfig } from '@cdktf/provider-cloudflare/lib/zone-cache-variants/index.js' -import { ZoneDnssecConfig } from '@cdktf/provider-cloudflare/lib/zone-dnssec/index.js' -import { ZoneHoldConfig } from '@cdktf/provider-cloudflare/lib/zone-hold/index.js' -import { ZoneLockdownConfig } from '@cdktf/provider-cloudflare/lib/zone-lockdown/index.js' -import { ZoneSettingConfig } from '@cdktf/provider-cloudflare/lib/zone-setting/index.js' -import { ZoneDnsSettingsConfig } from '@cdktf/provider-cloudflare/lib/zone-dns-settings/index.js' -import { DataCloudflareZoneConfig } from '@cdktf/provider-cloudflare/lib/data-cloudflare-zone/index.js' +import { + GetZoneArgs, + ZoneArgs, + ZoneCacheReserveArgs, + ZoneCacheVariantsArgs, + ZoneDnssecArgs, + ZoneDnsSettingsArgs, + ZoneHoldArgs, + ZoneLockdownArgs, + ZoneSettingArgs, +} from '@pulumi/cloudflare' -export interface ZoneProps extends ZoneConfig {} -export interface ZoneOptions extends DataCloudflareZoneConfig { - id?: string - name?: string -} -export interface ZoneCacheReserveProps extends ZoneCacheReserveConfig {} -export interface ZoneCacheVariantsProps extends ZoneCacheVariantsConfig {} -export interface ZoneDnssecProps extends ZoneDnssecConfig {} -export interface ZoneHoldProps extends ZoneHoldConfig {} -export interface ZoneLockdownProps extends ZoneLockdownConfig {} -export interface ZoneSettingProps extends ZoneSettingConfig {} -export interface ZoneDnsSettingsProps extends ZoneDnsSettingsConfig {} +export interface ZoneProps extends ZoneArgs {} +export interface GetZoneProps extends GetZoneArgs {} +export interface ZoneCacheReserveProps extends ZoneCacheReserveArgs {} +export interface ZoneCacheVariantsProps extends ZoneCacheVariantsArgs {} +export interface ZoneDnssecProps extends ZoneDnssecArgs {} +export interface ZoneHoldProps extends ZoneHoldArgs {} +export interface ZoneLockdownProps extends ZoneLockdownArgs {} +export interface ZoneSettingProps extends ZoneSettingArgs {} +export interface ZoneDnsSettingsProps extends ZoneDnsSettingsArgs {} diff --git a/src/lib/cloudflare/utils/index.ts b/src/lib/cloudflare/utils/index.ts deleted file mode 100644 index 5e376b35..00000000 --- a/src/lib/cloudflare/utils/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { TerraformOutput } from 'cdktf' -import _ from 'lodash' -import { CommonCloudflareConstruct } from '../common/index.js' - -export const createCloudflareTfOutput = ( - id: string, - scope: CommonCloudflareConstruct, - value?: string, - description?: string, - sensitive?: boolean, - overrideId = true -) => { - const output = new TerraformOutput(scope, id, { - description, - sensitive, - value, - }) - - if (overrideId) { - output.overrideLogicalId(_.camelCase(id)) - } - return output -} diff --git a/src/lib/common/types.ts b/src/lib/common/types.ts index f95079b1..804b6f03 100644 --- a/src/lib/common/types.ts +++ b/src/lib/common/types.ts @@ -1,4 +1,7 @@ +import { ComponentResourceOptions } from '@pulumi/pulumi' + export interface BaseProps { + debug?: boolean domainName: string extraContexts?: string[] name: string @@ -7,3 +10,5 @@ export interface BaseProps { stageContextPath?: string subDomain?: string } + +export interface BaseOptions extends ComponentResourceOptions {} From 86684f2ffd6853551ce253fbca0e30d5840e5b8b Mon Sep 17 00:00:00 2001 From: Srinidhi Veeraraghavan Date: Fri, 19 Dec 2025 18:00:20 +0000 Subject: [PATCH 3/7] feat: updating access manager tests to test against pulumi --- .../cloudflare/common/cdkConfig/access.json | 6 +- .../services/access-manager.test.ts | 615 +++++++++++------- 2 files changed, 372 insertions(+), 249 deletions(-) diff --git a/src/test/cloudflare/common/cdkConfig/access.json b/src/test/cloudflare/common/cdkConfig/access.json index 1e1dc8a0..69251800 100644 --- a/src/test/cloudflare/common/cdkConfig/access.json +++ b/src/test/cloudflare/common/cdkConfig/access.json @@ -16,7 +16,7 @@ "type": "forbidden" }, "testAccessGroup": { - "include": [ + "includes": [ { "email": { "email": "test@gradientedge.io" @@ -42,7 +42,7 @@ }, "testAccessPolicy": { "decision": "allow", - "include": [ + "includes": [ { "email": { "email": "test@gradientedge.io" @@ -50,7 +50,7 @@ } ], "name": "test-policy-props", - "require": [ + "requires": [ { "email": { "email": "test@gradientedge.io" diff --git a/src/test/cloudflare/services/access-manager.test.ts b/src/test/cloudflare/services/access-manager.test.ts index d007df67..7bf0bb7c 100644 --- a/src/test/cloudflare/services/access-manager.test.ts +++ b/src/test/cloudflare/services/access-manager.test.ts @@ -1,6 +1,18 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' +import { + AccessRule, + ZeroTrustAccessApplication, + ZeroTrustAccessCustomPage, + ZeroTrustAccessGroup, + ZeroTrustAccessIdentityProvider, + ZeroTrustAccessMtlsCertificate, + ZeroTrustAccessPolicy, + ZeroTrustAccessServiceToken, + ZeroTrustAccessShortLivedCertificate, + ZeroTrustAccessTag, + ZeroTrustOrganization, + Zone, +} from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' import fs from 'fs' import { AccessRuleProps, @@ -44,397 +56,508 @@ const testStackProps: any = { 'src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/zone.json', ], - features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', stageContextPath: 'src/test/aws/common/cdkEnv', } -class TestCommonStack extends CommonCloudflareStack { +class TestCommonCloudflareStack extends CommonCloudflareStack { declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAccessApplication: this.node.tryGetContext('testAccessApplication'), - testAccessCustomPage: this.node.tryGetContext('testAccessCustomPage'), - testAccessGroup: this.node.tryGetContext('testAccessGroup'), - testAccessMTlsCertificate: this.node.tryGetContext('testAccessMTlsCertificate'), - testAccessOTPIdentityProvider: this.node.tryGetContext('testAccessOTPIdentityProvider'), - testAccessOrganisation: this.node.tryGetContext('testAccessOrganisation'), - testAccessPolicy: this.node.tryGetContext('testAccessPolicy'), - testAccessRuleChallenge: this.node.tryGetContext('testAccessRuleChallenge'), - testAccessRuleWhitelist: this.node.tryGetContext('testAccessRuleWhitelist'), - testAccessSamlIdentityProvider: this.node.tryGetContext('testAccessSamlIdentityProvider'), - testAccessServiceToken: this.node.tryGetContext('testAccessServiceToken'), - testAccessTag: this.node.tryGetContext('testAccessTag'), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) } } -class TestInvalidCommonStack extends CommonCloudflareStack { +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) } protected determineConstructProps(props: CommonCloudflareStackProps) { return { ...super.determineConstructProps(props), - testAccessCustomPage: this.node.tryGetContext('testAccessCustomPage'), - testAccessGroup: this.node.tryGetContext('testAccessGroup'), - testAccessMTlsCertificate: this.node.tryGetContext('testAccessMTlsCertificate'), - testAccessOTPIdentityProvider: this.node.tryGetContext('testAccessOTPIdentityProvider'), - testAccessOrganisation: this.node.tryGetContext('testAccessOrganisation'), - testAccessPolicy: this.node.tryGetContext('testAccessPolicy'), - testAccessRuleChallenge: this.node.tryGetContext('testAccessRuleChallenge'), - testAccessRuleWhitelist: this.node.tryGetContext('testAccessRuleWhitelist'), - testAccessSamlIdentityProvider: this.node.tryGetContext('testAccessSamlIdentityProvider'), - testAccessServiceToken: this.node.tryGetContext('testAccessServiceToken'), - testAccessTag: this.node.tryGetContext('testAccessTag'), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), + testAccessApplication: undefined, } } } class TestCommonConstruct extends CommonCloudflareConstruct { declare props: TestCloudflareStackProps + zone: Zone + accessApp: ZeroTrustAccessApplication + accessCertificate: ZeroTrustAccessShortLivedCertificate + accessCustomPage: ZeroTrustAccessCustomPage + accessGroup: ZeroTrustAccessGroup + accessIdentityProviderOTP: ZeroTrustAccessIdentityProvider + accessIdentityProviderSAML: ZeroTrustAccessIdentityProvider + accessMTLS: ZeroTrustAccessMtlsCertificate + accessOrganisation: ZeroTrustOrganization + accessPolicy: ZeroTrustAccessPolicy + accessRuleChallenge: AccessRule + accessRuleWhitelist: AccessRule + accessServiceToken: ZeroTrustAccessServiceToken + accessTag: ZeroTrustAccessTag - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - const zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - const accessApp = this.accessManager.createAccessApplication( + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.accessApp = this.accessManager.createAccessApplication( `test-access-app-${this.props.stage}`, this, this.props.testAccessApplication ) - this.accessManager.createAccessShortLivedCertificate(`test-access-ca-cert-${this.props.stage}`, this, { - appId: accessApp.id, - }) - this.accessManager.createAccessCustomPage(`test-access-custom-page-${this.props.stage}`, this, { - ...this.props.testAccessCustomPage, - customHtml: fs.readFileSync('src/test/cloudflare/common/sample.html', { encoding: 'utf8' }), - }) - this.accessManager.createAccessGroup(`test-access-grp-${this.props.stage}`, this, this.props.testAccessGroup) - this.accessManager.createAccessIdentityProvider( + this.accessCertificate = this.accessManager.createAccessShortLivedCertificate( + `test-access-ca-cert-${this.props.stage}`, + this, + { + appId: this.accessApp.id, + } + ) + this.accessCustomPage = this.accessManager.createAccessCustomPage( + `test-access-custom-page-${this.props.stage}`, + this, + { + ...this.props.testAccessCustomPage, + customHtml: fs.readFileSync('src/test/cloudflare/common/sample.html', { encoding: 'utf8' }), + } + ) + this.accessGroup = this.accessManager.createAccessGroup( + `test-access-grp-${this.props.stage}`, + this, + this.props.testAccessGroup + ) + this.accessIdentityProviderOTP = this.accessManager.createAccessIdentityProvider( `test-access-idp-otp-${this.props.stage}`, this, this.props.testAccessOTPIdentityProvider ) - this.accessManager.createAccessIdentityProvider( + this.accessIdentityProviderSAML = this.accessManager.createAccessIdentityProvider( `test-access-idp-saml-${this.props.stage}`, this, this.props.testAccessSamlIdentityProvider ) - this.accessManager.createAccessMutualTlsCertificate(`test-access-mtls-${this.props.stage}`, this, { - ...this.props.testAccessMTlsCertificate, - certificate: fs.readFileSync('src/test/cloudflare/common/sample.pem', { encoding: 'utf8' }), - }) - this.accessManager.createAccessOrganization( + this.accessMTLS = this.accessManager.createAccessMutualTlsCertificate( + `test-access-mtls-${this.props.stage}`, + this, + { + ...this.props.testAccessMTlsCertificate, + certificate: fs.readFileSync('src/test/cloudflare/common/sample.pem', { encoding: 'utf8' }), + } + ) + this.accessOrganisation = this.accessManager.createAccessOrganization( `test-access-org-${this.props.stage}`, this, this.props.testAccessOrganisation ) - this.accessManager.createAccessPolicy(`test-access-policy-${this.props.stage}`, this, this.props.testAccessPolicy) - this.accessManager.createAccessRule( + this.accessPolicy = this.accessManager.createAccessPolicy( + `test-access-policy-${this.props.stage}`, + this, + this.props.testAccessPolicy + ) + this.accessRuleChallenge = this.accessManager.createAccessRule( `test-access-rule-ch-${this.props.stage}`, this, this.props.testAccessRuleChallenge ) - this.accessManager.createAccessRule( + this.accessRuleWhitelist = this.accessManager.createAccessRule( `test-access-rule-wl-${this.props.stage}`, this, this.props.testAccessRuleWhitelist ) - this.accessManager.createAccessServiceToken( + this.accessServiceToken = this.accessManager.createAccessServiceToken( `test-access-ser-token-${this.props.stage}`, this, this.props.testAccessServiceToken ) - this.accessManager.createAccessTag(`test-access-tag-${this.props.stage}`, this, this.props.testAccessTag) + this.accessTag = this.accessManager.createAccessTag( + `test-access-tag-${this.props.stage}`, + this, + this.props.testAccessTag + ) } } -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) describe('TestCloudflareAccessManager', () => { test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-access-app-dev') + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() }) }) describe('TestCloudflareAccessManager', () => { test('is initialised as expected', () => { /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareAccessManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareAccessManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testAccessAppDevAccessApplicationFriendlyUniqueId: { value: 'test-access-app-dev' }, - testAccessAppDevAccessApplicationId: { - value: '${cloudflare_zero_trust_access_application.test-access-app-dev.id}', - }, - testAccessCustomPageDevAccessCustomPageFriendlyUniqueId: { value: 'test-access-custom-page-dev' }, - testAccessCustomPageDevAccessCustomPageId: { - value: '${cloudflare_zero_trust_access_custom_page.test-access-custom-page-dev.id}', - }, - testAccessGrpDevAccessGroupFriendlyUniqueId: { value: 'test-access-grp-dev' }, - testAccessGrpDevAccessGroupId: { value: '${cloudflare_zero_trust_access_group.test-access-grp-dev.id}' }, - testAccessIdpOtpDevAccessIdentityProviderFriendlyUniqueId: { value: 'test-access-idp-otp-dev' }, - testAccessIdpOtpDevAccessIdentityProviderId: { - value: '${cloudflare_zero_trust_access_identity_provider.test-access-idp-otp-dev.id}', - }, - testAccessIdpSamlDevAccessIdentityProviderFriendlyUniqueId: { value: 'test-access-idp-saml-dev' }, - testAccessIdpSamlDevAccessIdentityProviderId: { - value: '${cloudflare_zero_trust_access_identity_provider.test-access-idp-saml-dev.id}', - }, - testAccessMtlsDevAccessMutualTlsCertificateFriendlyUniqueId: { value: 'test-access-mtls-dev' }, - testAccessMtlsDevAccessMutualTlsCertificateId: { - value: '${cloudflare_zero_trust_access_mtls_certificate.test-access-mtls-dev.id}', - }, - testAccessOrgDevAccessOrganizationFriendlyUniqueId: { value: 'test-access-org-dev' }, - testAccessPolicyDevAccessPolicyFriendlyUniqueId: { value: 'test-access-policy-dev' }, - testAccessPolicyDevAccessPolicyId: { value: '${cloudflare_zero_trust_access_policy.test-access-policy-dev.id}' }, - testAccessRuleChDevAccessRuleFriendlyUniqueId: { value: 'test-access-rule-ch-dev' }, - testAccessRuleChDevAccessRuleId: { value: '${cloudflare_access_rule.test-access-rule-ch-dev.id}' }, - testAccessRuleWlDevAccessRuleFriendlyUniqueId: { value: 'test-access-rule-wl-dev' }, - testAccessRuleWlDevAccessRuleId: { value: '${cloudflare_access_rule.test-access-rule-wl-dev.id}' }, - testAccessSerTokenDevAccessServiceTokenFriendlyUniqueId: { value: 'test-access-ser-token-dev' }, - testAccessSerTokenDevAccessServiceTokenId: { - value: '${cloudflare_zero_trust_access_service_token.test-access-ser-token-dev.id}', - }, - testAccessTagDevAccessTagFriendlyUniqueId: { value: 'test-access-tag-dev' }, - testAccessTagDevAccessTagId: { value: '${cloudflare_zero_trust_access_tag.test-access-tag-dev.id}' }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, + expect(stack.props).toHaveProperty('testAttribute') + expect(stack.props.testAttribute).toEqual('success') + pulumi.all([stack.urn]).apply(([urn]) => { + expect(urn).toEqual('urn:pulumi:stack::project::custom:cloudflare:Stack:test-stack::test-stack') }) }) }) describe('TestCloudflareAccessManager', () => { + expect(stack.construct.zone).toBeDefined() test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') }) - ) }) }) describe('TestCloudflareAccessManager', () => { test('provisions access application as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessApplication', { - cors_headers: { - allow_all_headers: true, - allow_credentials: true, - allowed_origins: ['https://example.gradientedge.io'], - max_age: 10, - }, - domain: 'myapp-gradientedge.io', - name: 'test-app-dev', - session_duration: '24h', - type: 'self_hosted', - zone_id: '${data.cloudflare_zone.test-access-app-dev-data-zone-data-zone.zone_id}', + expect(stack.construct.accessApp).toBeDefined() + pulumi + .all([ + stack.construct.accessApp.id, + stack.construct.accessApp.urn, + stack.construct.accessApp.name, + stack.construct.accessApp.domain, + stack.construct.accessApp.sessionDuration, + stack.construct.accessApp.type, + stack.construct.accessApp.zoneId, + stack.construct.accessApp.corsHeaders, + ]) + .apply(([id, urn, name, domain, sessionDuration, type, zoneId, corsHeaders]) => { + expect(id).toEqual('test-access-app-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessApplication:ZeroTrustAccessApplication::test-access-app-dev' + ) + expect(name).toEqual('test-app-dev') + expect(domain).toEqual('myapp-gradientedge.io') + expect(sessionDuration).toEqual('24h') + expect(type).toEqual('self_hosted') + expect(zoneId).toEqual('test-access-app-dev-data-zone') + expect(corsHeaders).toEqual({ + allowAllHeaders: true, + allowCredentials: true, + allowedOrigins: ['https://example.gradientedge.io'], + maxAge: 10, + }) }) - ) }) }) describe('TestCloudflareAccessManager', () => { - test('provisions access ca certificate as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessShortLivedCertificate', { - app_id: '${cloudflare_zero_trust_access_application.test-access-app-dev.id}', - zone_id: '${data.cloudflare_zone.test-access-ca-cert-dev-data-zone-data-zone.zone_id}', + test('provisions ca certificate as expected', () => { + expect(stack.construct.accessApp).toBeDefined() + pulumi + .all([ + stack.construct.accessCertificate.id, + stack.construct.accessCertificate.urn, + stack.construct.accessCertificate.accountId, + stack.construct.accessCertificate.appId, + stack.construct.accessCertificate.zoneId, + ]) + .apply(([id, urn, accountId, appId, zoneId]) => { + expect(id).toEqual('test-access-ca-cert-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessShortLivedCertificate:ZeroTrustAccessShortLivedCertificate::test-access-ca-cert-dev' + ) + expect(appId).toEqual('test-access-app-dev-id') + expect(zoneId).toEqual('test-access-ca-cert-dev-data-zone') }) - ) }) }) describe('TestCloudflareAccessManager', () => { test('provisions access custom page as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessCustomPage', { - account_id: '${var.accountId}', - custom_html: - "\n\n \n 403 Forbidden\n \n \n

403 Forbidden

\n

Sorry, you don't have access to this resource.

\n \n\n", - name: '403-dev', - type: 'forbidden', + expect(stack.construct.accessCustomPage).toBeDefined() + pulumi + .all([ + stack.construct.accessCustomPage.id, + stack.construct.accessCustomPage.urn, + stack.construct.accessCustomPage.name, + stack.construct.accessCustomPage.type, + stack.construct.accessCustomPage.customHtml, + ]) + .apply(([id, urn, name, type, customHtml]) => { + expect(id).toEqual('test-access-custom-page-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessCustomPage:ZeroTrustAccessCustomPage::test-access-custom-page-dev' + ) + expect(name).toEqual('403-dev') + expect(type).toEqual('forbidden') + expect(customHtml).toEqual( + "\n\n \n 403 Forbidden\n \n \n

403 Forbidden

\n

Sorry, you don't have access to this resource.

\n \n\n" + ) }) - ) }) }) describe('TestCloudflareAccessManager', () => { test('provisions access group as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessGroup', { - include: [ + expect(stack.construct.accessGroup).toBeDefined() + pulumi + .all([ + stack.construct.accessGroup.id, + stack.construct.accessGroup.urn, + stack.construct.accessGroup.name, + stack.construct.accessGroup.zoneId, + stack.construct.accessGroup.includes, + ]) + .apply(([id, urn, name, zoneId, includes]) => { + expect(id).toEqual('test-access-grp-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessGroup:ZeroTrustAccessGroup::test-access-grp-dev' + ) + expect(includes).toEqual([ { email: { email: 'test@gradientedge.io', }, }, - ], - name: 'test-group - DEV', - zone_id: '${data.cloudflare_zone.test-access-grp-dev-data-zone-data-zone.zone_id}', + ]) + expect(name).toEqual('test-group - DEV') + expect(zoneId).toEqual('test-access-grp-dev-data-zone') }) - ) }) }) describe('TestCloudflareAccessManager', () => { - test('provisions access identity provider as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessIdentityProvider', { - name: 'test-idp-otp-dev', - type: 'onetimepin', - zone_id: '${data.cloudflare_zone.test-access-idp-otp-dev-data-zone-data-zone.zone_id}', + test('provisions access identity provider OTP as expected', () => { + expect(stack.construct.accessIdentityProviderOTP).toBeDefined() + pulumi + .all([ + stack.construct.accessIdentityProviderOTP.id, + stack.construct.accessIdentityProviderOTP.urn, + stack.construct.accessIdentityProviderOTP.name, + stack.construct.accessIdentityProviderOTP.type, + stack.construct.accessIdentityProviderOTP.zoneId, + ]) + .apply(([id, urn, name, type, zoneId]) => { + expect(id).toEqual('test-access-idp-otp-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessIdentityProvider:ZeroTrustAccessIdentityProvider::test-access-idp-otp-dev' + ) + expect(name).toEqual('test-idp-otp-dev') + expect(type).toEqual('onetimepin') + expect(zoneId).toEqual('test-access-idp-otp-dev-data-zone') }) - ) - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessIdentityProvider', { - config: { - attributes: ['email', 'username'], - }, - name: 'test-idp-saml-dev', - type: 'saml', - zone_id: '${data.cloudflare_zone.test-access-idp-saml-dev-data-zone-data-zone.zone_id}', + }) +}) + +describe('TestCloudflareAccessManager', () => { + test('provisions access identity provider SAML as expected', () => { + expect(stack.construct.accessIdentityProviderSAML).toBeDefined() + pulumi + .all([ + stack.construct.accessIdentityProviderSAML.id, + stack.construct.accessIdentityProviderSAML.urn, + stack.construct.accessIdentityProviderSAML.name, + stack.construct.accessIdentityProviderSAML.type, + stack.construct.accessIdentityProviderSAML.zoneId, + ]) + .apply(([id, urn, name, type, zoneId]) => { + expect(id).toEqual('test-access-idp-saml-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessIdentityProvider:ZeroTrustAccessIdentityProvider::test-access-idp-saml-dev' + ) + expect(name).toEqual('test-idp-saml-dev') + expect(type).toEqual('saml') + expect(zoneId).toEqual('test-access-idp-saml-dev-data-zone') }) - ) }) }) describe('TestCloudflareAccessManager', () => { - test('provisions access mTls certificate as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessMtlsCertificate', { - associated_hostnames: ['test.gradientedge.io'], - certificate: - '-----BEGIN CERTIFICATE-----\nMIIDtzCCAp+gAwIBAgIUMPxgg0ZUXMgZuijIGEZnl4Yf9YswDQYJKoZIhvcNAQEL\nBQAwazELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAcM\nBkxvbmRvbjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYD\nVQQDDApleGFtcGxlLmlvMB4XDTIzMTEyMjEwMjEwMVoXDTI0MTEyMTEwMjEwMVow\nazELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAcMBkxv\nbmRvbjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD\nDApleGFtcGxlLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkZXE\njgNIkA7eqXFmR5NNd87K0UpUxDlVm9lRdKFNPAcuaMK/APEx4nIIEIMSUa2d9V9E\nxNXzSPz96S1li+kzVT9wkh7UYVo1jhod1UmIFw6JTovH2iGldzTo7XXcS2UT2pml\nHZLBr8VsDlseuzqA6EaErDsRZk6aZ2BGVmdhAanDnjzY5nO+XTpmcBS1u5TTNKQ6\nikhAhF7hNvHRbsZRbwXaMdUkEUPS+2lkCoSwo8UJJLpJlbD5RvnIRmyKClpLWBNZ\nwr0W4lyL0RGqUX8TqmZN/LmKW5GFOlLQID+4Xx8FDQEby8eEhAmg8I3SX1Ui4bY3\nR5Oa2+uxOcL1wj0hIQIDAQABo1MwUTAdBgNVHQ4EFgQUF2ZOdkKBfHsVWvgldNTU\n9oKAMtUwHwYDVR0jBBgwFoAUF2ZOdkKBfHsVWvgldNTU9oKAMtUwDwYDVR0TAQH/\nBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVM1NGKM2rUFQ7IOOAcjLNoNNxz39\ntdbv0pHA+domm0FDXwDt3/fJL1qyUSMRJflnmqcIyT9+7a43nj42ip7NqbUh0B7X\nKxWR9vqajL49Eb6+nO0V8dVi9DJzqLxF2aQNMQ8KBtI2NZdaNGVJIqajgXr4fJ/G\nTlko8IAooQk+E2Ov4U/vwE1ISqVeuBsI0bTHMap9+1q+rWy8blmv5m8LZi8f/q7F\nZGXKnWWCm9TqsTf38xesu7osXtUM8+10FY4EWlh1mWBy2SeVgdgAkJACM4LGamFA\nymD5YcAsI4/RIGzp/JMjJpvhFdBbvZkxH3XIcNZ7rfeCEN5mVKJW/B1OEg==\n-----END CERTIFICATE-----\n-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCRlcSOA0iQDt6p\ncWZHk013zsrRSlTEOVWb2VF0oU08By5owr8A8THicggQgxJRrZ31X0TE1fNI/P3p\nLWWL6TNVP3CSHtRhWjWOGh3VSYgXDolOi8faIaV3NOjtddxLZRPamaUdksGvxWwO\nWx67OoDoRoSsOxFmTppnYEZWZ2EBqcOePNjmc75dOmZwFLW7lNM0pDqKSECEXuE2\n8dFuxlFvBdox1SQRQ9L7aWQKhLCjxQkkukmVsPlG+chGbIoKWktYE1nCvRbiXIvR\nEapRfxOqZk38uYpbkYU6UtAgP7hfHwUNARvLx4SECaDwjdJfVSLhtjdHk5rb67E5\nwvXCPSEhAgMBAAECggEACW3GO55Z0j6sTBQUmDkhkMtbVl+2irjd4wiZnnCd9G/Q\noSdPwItefDh/bjZW9uREMTKY3RiwN39vIG14wK17Th+cNlJ51c5GXqwxV3F6N2gR\nG32xFV8NfOF33n0+JcHnncZKq9Yn5i7mly1umZip5aE/kXoH3/TiSiSxmYH7heR0\nQZkkS+jsFPhjD6nhz0xDDJiY/1cCQ0sUvRne4G1kqN8J0Z7FMrg7cb5wZVDMRc1S\n1px6xGjSOMnMgPYRvCxEPw7Pge3J+XYg4EIiDkeU5XmtXPsNsZR5iVgoAnfgrU/N\n1oiFNYZtohl8M4NHcZy6I1C23iWAL+plJ6zOyiNmEwKBgQDNTZA+sfAg4iTLXyFg\ncgyFv5tEb2qgd1cWomFNbFyQ8ckc+EKhR7xwv1P1VXXCnqcWjqizmb0uOJpczvU6\nVPXv7kFg0CK5cnngkSFi7VimACbqvXDk8n5XI9x9xiDDEUwOZsPzs+1KGj41Cd0K\nHkRtnOjEOQF3YmLm3v1l+iPY5wKBgQC1iRLHjsKFwQUEhWOMOMqJLQrLlnpAtRpd\nrHEncMzm3NolQX+F7JM5tKCBsMtnVZG16jeACW1RENgmRYWvK4P/DdbDb28JIlD2\nMigMveNZbS0IMdbDlte0PEwUvAQrmtCxVDimDgsSi2HLcAZ1wIb3q9Oe2lE4pleZ\nxJf/PnPMtwKBgQCwg56geOanryfJf2o3/PbNS/dYOJ8phlHnUQdtxNw1dtzePokz\nF3VqTuYFyktsYHHykAd2G5mvEtWNNBdd5sxpVKT7cxhX75fgP4fAAac1Wm4bZ3OY\nNPHxRBEARofGj6mfvDV/49QB4VxYx7k3SNy2jbEHfKfJGFtGerTNp+qIQwKBgQCg\nCPIsSLdF0M6KmMkUgbBTVAjzR3oI918B+5ZZbcDFOSd6to4kU1XLBmiFTIVUWIQ2\n+f7peeYMFCxpONrMfTFFNT8CVYduZvk2wSq7aN83I98SHVW2YZFRS+LKWKHYiwe1\nfIjgIvsx4vxYqy6Wuh6B0tGhddcqeMI7Rau1kanmawKBgQCQE/orMbiFQ5ahEJsc\nCeX4ZId/12bWDtjjy/krQ7F7da0CRAnYsC9MqW+Zc4uvylNhPvRKKPLaF3XZPHvO\nn/ulnABB3u1RDx0Q9VFFs4DlgGxZEnC5aGiCaCBqk9RpFcqNWMBJfOWvHfnT1DtD\nZBR/sYHXYZuRdIzorWIxVZdMDw==\n-----END PRIVATE KEY-----', - name: 'test-mtls-cert-dev', - zone_id: '${data.cloudflare_zone.test-access-mtls-dev-data-zone-data-zone.zone_id}', + test('provisions access mTLS certificate as expected', () => { + expect(stack.construct.accessMTLS).toBeDefined() + pulumi + .all([ + stack.construct.accessMTLS.id, + stack.construct.accessMTLS.urn, + stack.construct.accessMTLS.name, + stack.construct.accessMTLS.zoneId, + stack.construct.accessMTLS.associatedHostnames, + stack.construct.accessMTLS.certificate, + ]) + .apply(([id, urn, name, zoneId, associatedHostnames, certificate]) => { + expect(id).toEqual('test-access-mtls-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessMtlsCertificate:ZeroTrustAccessMtlsCertificate::test-access-mtls-dev' + ) + expect(name).toEqual('test-mtls-cert-dev') + expect(zoneId).toEqual('test-access-mtls-dev-data-zone') + expect(associatedHostnames).toEqual(['test.gradientedge.io']) + expect(certificate).toEqual( + '-----BEGIN CERTIFICATE-----\nMIIDtzCCAp+gAwIBAgIUMPxgg0ZUXMgZuijIGEZnl4Yf9YswDQYJKoZIhvcNAQEL\nBQAwazELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAcM\nBkxvbmRvbjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYD\nVQQDDApleGFtcGxlLmlvMB4XDTIzMTEyMjEwMjEwMVoXDTI0MTEyMTEwMjEwMVow\nazELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAcMBkxv\nbmRvbjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD\nDApleGFtcGxlLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkZXE\njgNIkA7eqXFmR5NNd87K0UpUxDlVm9lRdKFNPAcuaMK/APEx4nIIEIMSUa2d9V9E\nxNXzSPz96S1li+kzVT9wkh7UYVo1jhod1UmIFw6JTovH2iGldzTo7XXcS2UT2pml\nHZLBr8VsDlseuzqA6EaErDsRZk6aZ2BGVmdhAanDnjzY5nO+XTpmcBS1u5TTNKQ6\nikhAhF7hNvHRbsZRbwXaMdUkEUPS+2lkCoSwo8UJJLpJlbD5RvnIRmyKClpLWBNZ\nwr0W4lyL0RGqUX8TqmZN/LmKW5GFOlLQID+4Xx8FDQEby8eEhAmg8I3SX1Ui4bY3\nR5Oa2+uxOcL1wj0hIQIDAQABo1MwUTAdBgNVHQ4EFgQUF2ZOdkKBfHsVWvgldNTU\n9oKAMtUwHwYDVR0jBBgwFoAUF2ZOdkKBfHsVWvgldNTU9oKAMtUwDwYDVR0TAQH/\nBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVM1NGKM2rUFQ7IOOAcjLNoNNxz39\ntdbv0pHA+domm0FDXwDt3/fJL1qyUSMRJflnmqcIyT9+7a43nj42ip7NqbUh0B7X\nKxWR9vqajL49Eb6+nO0V8dVi9DJzqLxF2aQNMQ8KBtI2NZdaNGVJIqajgXr4fJ/G\nTlko8IAooQk+E2Ov4U/vwE1ISqVeuBsI0bTHMap9+1q+rWy8blmv5m8LZi8f/q7F\nZGXKnWWCm9TqsTf38xesu7osXtUM8+10FY4EWlh1mWBy2SeVgdgAkJACM4LGamFA\nymD5YcAsI4/RIGzp/JMjJpvhFdBbvZkxH3XIcNZ7rfeCEN5mVKJW/B1OEg==\n-----END CERTIFICATE-----\n-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCRlcSOA0iQDt6p\ncWZHk013zsrRSlTEOVWb2VF0oU08By5owr8A8THicggQgxJRrZ31X0TE1fNI/P3p\nLWWL6TNVP3CSHtRhWjWOGh3VSYgXDolOi8faIaV3NOjtddxLZRPamaUdksGvxWwO\nWx67OoDoRoSsOxFmTppnYEZWZ2EBqcOePNjmc75dOmZwFLW7lNM0pDqKSECEXuE2\n8dFuxlFvBdox1SQRQ9L7aWQKhLCjxQkkukmVsPlG+chGbIoKWktYE1nCvRbiXIvR\nEapRfxOqZk38uYpbkYU6UtAgP7hfHwUNARvLx4SECaDwjdJfVSLhtjdHk5rb67E5\nwvXCPSEhAgMBAAECggEACW3GO55Z0j6sTBQUmDkhkMtbVl+2irjd4wiZnnCd9G/Q\noSdPwItefDh/bjZW9uREMTKY3RiwN39vIG14wK17Th+cNlJ51c5GXqwxV3F6N2gR\nG32xFV8NfOF33n0+JcHnncZKq9Yn5i7mly1umZip5aE/kXoH3/TiSiSxmYH7heR0\nQZkkS+jsFPhjD6nhz0xDDJiY/1cCQ0sUvRne4G1kqN8J0Z7FMrg7cb5wZVDMRc1S\n1px6xGjSOMnMgPYRvCxEPw7Pge3J+XYg4EIiDkeU5XmtXPsNsZR5iVgoAnfgrU/N\n1oiFNYZtohl8M4NHcZy6I1C23iWAL+plJ6zOyiNmEwKBgQDNTZA+sfAg4iTLXyFg\ncgyFv5tEb2qgd1cWomFNbFyQ8ckc+EKhR7xwv1P1VXXCnqcWjqizmb0uOJpczvU6\nVPXv7kFg0CK5cnngkSFi7VimACbqvXDk8n5XI9x9xiDDEUwOZsPzs+1KGj41Cd0K\nHkRtnOjEOQF3YmLm3v1l+iPY5wKBgQC1iRLHjsKFwQUEhWOMOMqJLQrLlnpAtRpd\nrHEncMzm3NolQX+F7JM5tKCBsMtnVZG16jeACW1RENgmRYWvK4P/DdbDb28JIlD2\nMigMveNZbS0IMdbDlte0PEwUvAQrmtCxVDimDgsSi2HLcAZ1wIb3q9Oe2lE4pleZ\nxJf/PnPMtwKBgQCwg56geOanryfJf2o3/PbNS/dYOJ8phlHnUQdtxNw1dtzePokz\nF3VqTuYFyktsYHHykAd2G5mvEtWNNBdd5sxpVKT7cxhX75fgP4fAAac1Wm4bZ3OY\nNPHxRBEARofGj6mfvDV/49QB4VxYx7k3SNy2jbEHfKfJGFtGerTNp+qIQwKBgQCg\nCPIsSLdF0M6KmMkUgbBTVAjzR3oI918B+5ZZbcDFOSd6to4kU1XLBmiFTIVUWIQ2\n+f7peeYMFCxpONrMfTFFNT8CVYduZvk2wSq7aN83I98SHVW2YZFRS+LKWKHYiwe1\nfIjgIvsx4vxYqy6Wuh6B0tGhddcqeMI7Rau1kanmawKBgQCQE/orMbiFQ5ahEJsc\nCeX4ZId/12bWDtjjy/krQ7F7da0CRAnYsC9MqW+Zc4uvylNhPvRKKPLaF3XZPHvO\nn/ulnABB3u1RDx0Q9VFFs4DlgGxZEnC5aGiCaCBqk9RpFcqNWMBJfOWvHfnT1DtD\nZBR/sYHXYZuRdIzorWIxVZdMDw==\n-----END PRIVATE KEY-----' + ) }) - ) }) }) describe('TestCloudflareAccessManager', () => { test('provisions access organisation as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustOrganization', { - auth_domain: 'test.gradientedge.io', - auto_redirect_to_identity: false, - is_ui_read_only: false, - name: 'test-org-dev', - user_seat_expiration_inactive_time: '720h', - zone_id: '${data.cloudflare_zone.test-access-org-dev-data-zone-data-zone.zone_id}', - }) - ) + expect(stack.construct.accessOrganisation).toBeDefined() + pulumi + .all([ + stack.construct.accessOrganisation.id, + stack.construct.accessOrganisation.urn, + stack.construct.accessOrganisation.name, + stack.construct.accessOrganisation.zoneId, + stack.construct.accessOrganisation.authDomain, + stack.construct.accessOrganisation.autoRedirectToIdentity, + stack.construct.accessOrganisation.isUiReadOnly, + stack.construct.accessOrganisation.userSeatExpirationInactiveTime, + ]) + .apply( + ([id, urn, name, zoneId, authDomain, autoRedirectToIdentity, isUiReadOnly, userSeatExpirationInactiveTime]) => { + expect(id).toEqual('test-access-org-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustOrganization:ZeroTrustOrganization::test-access-org-dev' + ) + expect(name).toEqual('test-org-dev') + expect(zoneId).toEqual('test-access-org-dev-data-zone') + expect(authDomain).toEqual('test.gradientedge.io') + expect(autoRedirectToIdentity).toEqual(false) + expect(isUiReadOnly).toEqual(false) + expect(userSeatExpirationInactiveTime).toEqual('720h') + } + ) }) }) describe('TestCloudflareAccessManager', () => { - test('provisions access policy as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessPolicy', { - account_id: '${var.accountId}', - decision: 'allow', - include: [ + test('provisions access policies as expected', () => { + expect(stack.construct.accessPolicy).toBeDefined() + pulumi + .all([ + stack.construct.accessPolicy.id, + stack.construct.accessPolicy.urn, + stack.construct.accessPolicy.name, + stack.construct.accessPolicy.decision, + stack.construct.accessPolicy.includes, + stack.construct.accessPolicy.requires, + ]) + .apply(([id, urn, name, decision, includes, requires]) => { + expect(id).toEqual('test-access-policy-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessPolicy:ZeroTrustAccessPolicy::test-access-policy-dev' + ) + expect(name).toEqual('test-policy-props-dev') + expect(decision).toEqual('allow') + expect(includes).toEqual([ { email: { email: 'test@gradientedge.io', }, }, - ], - name: 'test-policy-props-dev', - require: [ + ]) + expect(requires).toEqual([ { email: { email: 'test@gradientedge.io', }, }, - ], + ]) }) - ) }) }) describe('TestCloudflareAccessManager', () => { - test('provisions access policy as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'AccessRule', { - account_id: '${var.accountId}', - mode: 'challenge', - notes: 'Requests coming from known for exit nodes', - zone_id: '${data.cloudflare_zone.test-access-rule-ch-dev-data-zone-data-zone.zone_id}', + test('provisions access challenge rule as expected', () => { + expect(stack.construct.accessRuleChallenge).toBeDefined() + pulumi + .all([ + stack.construct.accessRuleChallenge.id, + stack.construct.accessRuleChallenge.urn, + stack.construct.accessRuleChallenge.mode, + stack.construct.accessRuleChallenge.zoneId, + stack.construct.accessRuleChallenge.notes, + ]) + .apply(([id, urn, mode, zoneId, notes]) => { + expect(id).toEqual('test-access-rule-ch-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/accessRule:AccessRule::test-access-rule-ch-dev' + ) + expect(mode).toEqual('challenge') + expect(zoneId).toEqual('test-access-rule-ch-dev-data-zone') + expect(notes).toEqual('Requests coming from known for exit nodes') }) - ) - - expect( - Testing.toHaveResourceWithProperties(construct, 'AccessRule', { - account_id: '${var.accountId}', - mode: 'whitelist', - notes: 'Requests coming from Australia', - zone_id: '${data.cloudflare_zone.test-access-rule-wl-dev-data-zone-data-zone.zone_id}', + }) + test('provisions access challenge whitelist as expected', () => { + expect(stack.construct.accessRuleWhitelist).toBeDefined() + pulumi + .all([ + stack.construct.accessRuleWhitelist.id, + stack.construct.accessRuleWhitelist.urn, + stack.construct.accessRuleWhitelist.mode, + stack.construct.accessRuleWhitelist.zoneId, + stack.construct.accessRuleWhitelist.notes, + ]) + .apply(([id, urn, mode, zoneId, notes]) => { + expect(id).toEqual('test-access-rule-wl-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/accessRule:AccessRule::test-access-rule-wl-dev' + ) + expect(mode).toEqual('whitelist') + expect(zoneId).toEqual('test-access-rule-wl-dev-data-zone') + expect(notes).toEqual('Requests coming from Australia') }) - ) }) }) describe('TestCloudflareAccessManager', () => { test('provisions access service token as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessServiceToken', { - account_id: '${var.accountId}', - duration: '300ms', - name: 'test-service-token-dev', - zone_id: '${data.cloudflare_zone.test-access-ser-token-dev-data-zone-data-zone.zone_id}', + expect(stack.construct.accessServiceToken).toBeDefined() + pulumi + .all([ + stack.construct.accessServiceToken.id, + stack.construct.accessServiceToken.urn, + stack.construct.accessServiceToken.name, + stack.construct.accessServiceToken.zoneId, + stack.construct.accessServiceToken.duration, + ]) + .apply(([id, urn, name, zoneId, duration]) => { + expect(id).toEqual('test-access-ser-token-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessServiceToken:ZeroTrustAccessServiceToken::test-access-ser-token-dev' + ) + expect(name).toEqual('test-service-token-dev') + expect(zoneId).toEqual('test-access-ser-token-dev-data-zone') + expect(duration).toEqual('300ms') }) - ) }) }) describe('TestCloudflareAccessManager', () => { test('provisions access tag as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZeroTrustAccessTag', { - account_id: '${var.accountId}', - name: 'test-tag-dev', + expect(stack.construct.accessTag).toBeDefined() + pulumi + .all([stack.construct.accessTag.id, stack.construct.accessTag.urn, stack.construct.accessTag.name]) + .apply(([id, urn, name]) => { + expect(id).toEqual('test-access-tag-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zeroTrustAccessTag:ZeroTrustAccessTag::test-access-tag-dev' + ) + expect(name).toEqual('test-tag-dev') }) - ) }) }) From c76e21ab2966dcdab576b404969cd5c41e99e546 Mon Sep 17 00:00:00 2001 From: Srinidhi Veeraraghavan Date: Mon, 5 Jan 2026 14:49:23 +0000 Subject: [PATCH 4/7] feat(core): bREAKING CHANGES: switching to pulumi constructs BREAKING CHANGES: switching to pulumi constructs BREAKING CHANGE: switching to pulumi constructs from cdktf --- ...ts => common-cloudflare-construct.test.ts1} | 0 ...site.test.ts => pages-static-site.test.ts1} | 0 ...orker-site.test.ts => worker-site.test.ts1} | 0 ...ger.test.ts => api-shield-manager.test.ts1} | 0 ...o-manager.test.ts => argo-manager.test.ts1} | 0 ...nager.test.ts => firewall-manager.test.ts1} | 0 ...e-manager.test.ts => page-manager.test.ts1} | 0 ...manager.test.ts => record-manager.test.ts1} | 0 ...nager.test.ts => rule-set-manager.test.ts1} | 0 ...manager.test.ts => worker-manager.test.ts1} | 0 ...e-manager.test.ts => zone-manager.test.ts1} | 0 tsconfig.json | 18 +++++++++++++++++- 12 files changed, 17 insertions(+), 1 deletion(-) rename src/test/cloudflare/common/{common-cloudflare-construct.test.ts => common-cloudflare-construct.test.ts1} (100%) rename src/test/cloudflare/construct/{pages-static-site.test.ts => pages-static-site.test.ts1} (100%) rename src/test/cloudflare/construct/{worker-site.test.ts => worker-site.test.ts1} (100%) rename src/test/cloudflare/services/{api-shield-manager.test.ts => api-shield-manager.test.ts1} (100%) rename src/test/cloudflare/services/{argo-manager.test.ts => argo-manager.test.ts1} (100%) rename src/test/cloudflare/services/{firewall-manager.test.ts => firewall-manager.test.ts1} (100%) rename src/test/cloudflare/services/{page-manager.test.ts => page-manager.test.ts1} (100%) rename src/test/cloudflare/services/{record-manager.test.ts => record-manager.test.ts1} (100%) rename src/test/cloudflare/services/{rule-set-manager.test.ts => rule-set-manager.test.ts1} (100%) rename src/test/cloudflare/services/{worker-manager.test.ts => worker-manager.test.ts1} (100%) rename src/test/cloudflare/services/{zone-manager.test.ts => zone-manager.test.ts1} (100%) diff --git a/src/test/cloudflare/common/common-cloudflare-construct.test.ts b/src/test/cloudflare/common/common-cloudflare-construct.test.ts1 similarity index 100% rename from src/test/cloudflare/common/common-cloudflare-construct.test.ts rename to src/test/cloudflare/common/common-cloudflare-construct.test.ts1 diff --git a/src/test/cloudflare/construct/pages-static-site.test.ts b/src/test/cloudflare/construct/pages-static-site.test.ts1 similarity index 100% rename from src/test/cloudflare/construct/pages-static-site.test.ts rename to src/test/cloudflare/construct/pages-static-site.test.ts1 diff --git a/src/test/cloudflare/construct/worker-site.test.ts b/src/test/cloudflare/construct/worker-site.test.ts1 similarity index 100% rename from src/test/cloudflare/construct/worker-site.test.ts rename to src/test/cloudflare/construct/worker-site.test.ts1 diff --git a/src/test/cloudflare/services/api-shield-manager.test.ts b/src/test/cloudflare/services/api-shield-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/api-shield-manager.test.ts rename to src/test/cloudflare/services/api-shield-manager.test.ts1 diff --git a/src/test/cloudflare/services/argo-manager.test.ts b/src/test/cloudflare/services/argo-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/argo-manager.test.ts rename to src/test/cloudflare/services/argo-manager.test.ts1 diff --git a/src/test/cloudflare/services/firewall-manager.test.ts b/src/test/cloudflare/services/firewall-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/firewall-manager.test.ts rename to src/test/cloudflare/services/firewall-manager.test.ts1 diff --git a/src/test/cloudflare/services/page-manager.test.ts b/src/test/cloudflare/services/page-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/page-manager.test.ts rename to src/test/cloudflare/services/page-manager.test.ts1 diff --git a/src/test/cloudflare/services/record-manager.test.ts b/src/test/cloudflare/services/record-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/record-manager.test.ts rename to src/test/cloudflare/services/record-manager.test.ts1 diff --git a/src/test/cloudflare/services/rule-set-manager.test.ts b/src/test/cloudflare/services/rule-set-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/rule-set-manager.test.ts rename to src/test/cloudflare/services/rule-set-manager.test.ts1 diff --git a/src/test/cloudflare/services/worker-manager.test.ts b/src/test/cloudflare/services/worker-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/worker-manager.test.ts rename to src/test/cloudflare/services/worker-manager.test.ts1 diff --git a/src/test/cloudflare/services/zone-manager.test.ts b/src/test/cloudflare/services/zone-manager.test.ts1 similarity index 100% rename from src/test/cloudflare/services/zone-manager.test.ts rename to src/test/cloudflare/services/zone-manager.test.ts1 diff --git a/tsconfig.json b/tsconfig.json index 5f0f883a..36516fe0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,5 +24,21 @@ "typeRoots": ["node_modules/@types", "./node_modules"], "types": ["node", "vitest/globals"] }, - "include": ["index.ts", "src/**/*.ts", "app/**/*.ts"] + "include": [ + "index.ts", + "src/**/*.ts", + "app/**/*.ts", + "src/test/cloudflare/services/zone-manager.test.ts1", + "src/test/cloudflare/services/worker-manager.test.ts1", + "src/test/cloudflare/services/rule-set-manager.test.ts1", + "src/test/cloudflare/services/record-manager.test.ts1", + "src/test/cloudflare/services/page-manager.test.ts1", + "src/test/cloudflare/services/firewall-manager.test.ts1", + "src/test/cloudflare/services/argo-manager.test.ts1", + "src/test/cloudflare/services/api-shield-manager.test.ts1", + "src/test/cloudflare/services/access-manager.pulumi.test.ts1", + "src/test/cloudflare/construct/worker-site.test.ts1", + "src/test/cloudflare/construct/pages-static-site.test.ts1", + "src/test/cloudflare/common/common-cloudflare-construct.test.ts1" + ] } From 796529a3b776f4449c63db45ba5e84235719eeed Mon Sep 17 00:00:00 2001 From: Srinidhi Veeraraghavan Date: Tue, 6 Jan 2026 12:20:46 +0000 Subject: [PATCH 5/7] feat: updating cdktf references to pulumi --- src/lib/cloudflare/common/stack.ts | 9 ++++----- src/lib/cloudflare/construct/pages-static-site/main.ts | 8 ++++---- src/lib/cloudflare/construct/worker-site/main.ts | 6 +++--- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/lib/cloudflare/common/stack.ts b/src/lib/cloudflare/common/stack.ts index 4b73f56b..a6372b13 100644 --- a/src/lib/cloudflare/common/stack.ts +++ b/src/lib/cloudflare/common/stack.ts @@ -33,7 +33,7 @@ export class CommonCloudflareStack extends ComponentResource { } /** - * @summary Method to determine the core CDK construct properties injected via context cdktf.json + * @summary Method to determine the core CDK construct properties injected via context * @param props The stack properties * @returns The stack properties */ @@ -63,14 +63,13 @@ export class CommonCloudflareStack extends ComponentResource { } /** - * @summary Method to determine extra cdk contexts apart from the main cdktf.json + * @summary Method to determine extra cdk contexts apart from the main context * - Sets the properties from the extra contexts into cdk node context * - Primary use is to have layered config in separate files to enable easier maintenance and readability */ protected determineExtraContexts(props: CommonCloudflareStackProps) { if (!props.extraContexts) { - if (props.debug) - console.debug(`No additional contexts provided. Using default context properties from cdktf.json`) + if (props.debug) console.debug(`No additional contexts provided. Using default context properties`) return {} } @@ -95,7 +94,7 @@ export class CommonCloudflareStack extends ComponentResource { } /** - * @summary Method to determine extra cdk stage contexts apart from the main cdktf.json + * @summary Method to determine extra cdk stage contexts apart from the main context * - Sets the properties from the extra stage contexts into cdk node context * - Primary use is to have layered config for each environment which is injected into the context */ diff --git a/src/lib/cloudflare/construct/pages-static-site/main.ts b/src/lib/cloudflare/construct/pages-static-site/main.ts index 0c237646..82a4a2e0 100644 --- a/src/lib/cloudflare/construct/pages-static-site/main.ts +++ b/src/lib/cloudflare/construct/pages-static-site/main.ts @@ -1,10 +1,10 @@ -import { - PagesProjectDeploymentConfigsPreviewEnvVars, - PagesProjectDeploymentConfigsProductionEnvVars, -} from '@cdktf/provider-cloudflare/lib/pages-project/index.js' import * as aws from '@pulumi/aws' import * as azure from '@pulumi/azure-native' import { DnsRecord, PagesDomain, PagesProject, Zone } from '@pulumi/cloudflare' +import { + PagesProjectDeploymentConfigsPreviewEnvVars, + PagesProjectDeploymentConfigsProductionEnvVars, +} from '@pulumi/cloudflare/types/input.js' import { ComponentResourceOptions } from '@pulumi/pulumi' import * as std from '@pulumi/std' import { CommonCloudflareConstruct } from '../../common/index.js' diff --git a/src/lib/cloudflare/construct/worker-site/main.ts b/src/lib/cloudflare/construct/worker-site/main.ts index a2589f51..1e3ce4ec 100644 --- a/src/lib/cloudflare/construct/worker-site/main.ts +++ b/src/lib/cloudflare/construct/worker-site/main.ts @@ -1,7 +1,7 @@ -import { WorkersScriptBindings } from '@cdktf/provider-cloudflare/lib/workers-script/index.js' import * as aws from '@pulumi/aws' import * as azure from '@pulumi/azure-native' import { WorkersScript, Zone } from '@pulumi/cloudflare' +import { WorkersScriptBinding } from '@pulumi/cloudflare/types/input.js' import { ComponentResourceOptions } from '@pulumi/pulumi' import * as std from '@pulumi/std' import { CommonCloudflareConstruct } from '../../common/index.js' @@ -28,8 +28,8 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { /* worker site resources */ siteZone: Zone siteWorkerScript: WorkersScript - workerPlainTextBindingEnvironmentVariables: WorkersScriptBindings[] = [] - workerSecretTextBindingEnvironmentVariables: WorkersScriptBindings[] = [] + workerPlainTextBindingEnvironmentVariables: WorkersScriptBinding[] = [] + workerSecretTextBindingEnvironmentVariables: WorkersScriptBinding[] = [] constructor(id: string, props: CloudflareWorkerSiteProps, options?: ComponentResourceOptions) { super(id, props) From a98be90344f859465d62d6eb789dba535aee6e41 Mon Sep 17 00:00:00 2001 From: Srinidhi Veeraraghavan Date: Thu, 15 Jan 2026 17:20:04 +0000 Subject: [PATCH 6/7] feat: adding tests for cloudflare services --- src/lib/cloudflare/services/filter/main.ts | 4 +- .../cloudflare/common/cdkConfig/argo.json | 3 +- .../cloudflare/common/cdkConfig/filter.json | 10 +- .../cloudflare/common/cdkConfig/rule-set.json | 2 + .../cloudflare/common/cdkConfig/worker.json | 24 +- .../services/api-shield-manager.test.ts | 287 +++++++++++++++++ .../services/api-shield-manager.test.ts1 | 260 --------------- .../cloudflare/services/argo-manager.test.ts | 128 ++++++++ .../cloudflare/services/argo-manager.test.ts1 | 145 --------- .../services/firewall-manager.test.ts | 168 ++++++++++ .../services/firewall-manager.test.ts1 | 174 ---------- .../cloudflare/services/page-manager.test.ts | 234 ++++++++++++++ .../cloudflare/services/page-manager.test.ts1 | 214 ------------- .../services/record-manager.test.ts | 157 +++++++++ .../services/record-manager.test.ts1 | 158 ---------- .../services/rule-set-manager.test.ts | 123 ++++++++ .../services/rule-set-manager.test.ts1 | 143 --------- .../services/worker-manager.test.ts | 187 +++++++++++ .../services/worker-manager.test.ts1 | 297 ------------------ .../cloudflare/services/zone-manager.test.ts | 196 ++++++++++++ .../cloudflare/services/zone-manager.test.ts1 | 239 -------------- tsconfig.json | 16 +- 22 files changed, 1513 insertions(+), 1656 deletions(-) create mode 100644 src/test/cloudflare/services/api-shield-manager.test.ts delete mode 100644 src/test/cloudflare/services/api-shield-manager.test.ts1 create mode 100644 src/test/cloudflare/services/argo-manager.test.ts delete mode 100644 src/test/cloudflare/services/argo-manager.test.ts1 create mode 100644 src/test/cloudflare/services/firewall-manager.test.ts delete mode 100644 src/test/cloudflare/services/firewall-manager.test.ts1 create mode 100644 src/test/cloudflare/services/page-manager.test.ts delete mode 100644 src/test/cloudflare/services/page-manager.test.ts1 create mode 100644 src/test/cloudflare/services/record-manager.test.ts delete mode 100644 src/test/cloudflare/services/record-manager.test.ts1 create mode 100644 src/test/cloudflare/services/rule-set-manager.test.ts delete mode 100644 src/test/cloudflare/services/rule-set-manager.test.ts1 create mode 100644 src/test/cloudflare/services/worker-manager.test.ts delete mode 100644 src/test/cloudflare/services/worker-manager.test.ts1 create mode 100644 src/test/cloudflare/services/zone-manager.test.ts delete mode 100644 src/test/cloudflare/services/zone-manager.test.ts1 diff --git a/src/lib/cloudflare/services/filter/main.ts b/src/lib/cloudflare/services/filter/main.ts index 8fcaa226..ba7ee8b3 100644 --- a/src/lib/cloudflare/services/filter/main.ts +++ b/src/lib/cloudflare/services/filter/main.ts @@ -14,7 +14,7 @@ import { FilterProps } from './types.js' * constructor(parent: Construct, id: string, props: CommonCloudflareStackProps) { * super(parent, id, props) * this.props = props - * this.filterManager.createApiShield('MyFilter', this, props) + * this.filterManager.createFilter('MyFilter', this, props) * } * } * ``` @@ -27,7 +27,7 @@ export class CloudflareFilterManager { * @param props filter properties * @see [Pulumi Cloudflare Filter]{@link https://www.pulumi.com/registry/packages/cloudflare/api-docs/filter/} */ - public createApiShield(id: string, scope: CommonCloudflareConstruct, props: FilterProps) { + public createFilter(id: string, scope: CommonCloudflareConstruct, props: FilterProps) { if (!props) throw `Props undefined for ${id}` const zoneId = props.zoneId diff --git a/src/test/cloudflare/common/cdkConfig/argo.json b/src/test/cloudflare/common/cdkConfig/argo.json index c4ca9ce7..81b94ba1 100644 --- a/src/test/cloudflare/common/cdkConfig/argo.json +++ b/src/test/cloudflare/common/cdkConfig/argo.json @@ -1,6 +1,5 @@ { "testArgo": { - "tieredCaching": "on", - "smartRouting": "on" + "value": "on" } } diff --git a/src/test/cloudflare/common/cdkConfig/filter.json b/src/test/cloudflare/common/cdkConfig/filter.json index aa1cf70a..462f4902 100644 --- a/src/test/cloudflare/common/cdkConfig/filter.json +++ b/src/test/cloudflare/common/cdkConfig/filter.json @@ -1,7 +1,11 @@ { "testFilter": { - "description": "Site break-in attempts that are outside of the office", - "expression": "(http.request.uri.path ~ \".*wp-login.php\" or http.request.uri.path ~ \".*xmlrpc.php\") and ip.src ne 192.0.2.1", - "paused": false + "bodies": [ + { + "description": "Site break-in attempts that are outside of the office", + "expression": "(http.request.uri.path ~ \".*wp-login.php\" or http.request.uri.path ~ \".*xmlrpc.php\") and ip.src ne 192.0.2.1", + "paused": false + } + ] } } diff --git a/src/test/cloudflare/common/cdkConfig/rule-set.json b/src/test/cloudflare/common/cdkConfig/rule-set.json index 88838210..d5ed70b7 100644 --- a/src/test/cloudflare/common/cdkConfig/rule-set.json +++ b/src/test/cloudflare/common/cdkConfig/rule-set.json @@ -1,6 +1,8 @@ { "testRuleSet": { + "kind": "custom", "name": "testRuleSet", + "phase": "http*ratelimit", "rules": { "action": "set_cache_settings" } diff --git a/src/test/cloudflare/common/cdkConfig/worker.json b/src/test/cloudflare/common/cdkConfig/worker.json index 5f943c3e..fa1fa8c5 100644 --- a/src/test/cloudflare/common/cdkConfig/worker.json +++ b/src/test/cloudflare/common/cdkConfig/worker.json @@ -1,6 +1,19 @@ { + "testWorkerCronTrigger": { + "accountId": "test-account", + "schedules": [ + { + "cron": "*/5 * * * *" + }, + { + "cron": "10 7 * * mon-fri" + } + ], + "scriptName": "test-script" + }, "testWorkerDomain": { "accountId": "test-account", + "environment": "development", "hostname": "test.gradientedge.io", "service": "product-service" }, @@ -52,16 +65,5 @@ "testWorkersKvNamespace": { "accountId": "test-account", "title": "test-namespace" - }, - "testWorkerCronTrigger": { - "accountId": "test-account", - "schedules": [ - { - "cron": "*/5 * * * *" - }, - { - "cron": "10 7 * * mon-fri" - } - ] } } diff --git a/src/test/cloudflare/services/api-shield-manager.test.ts b/src/test/cloudflare/services/api-shield-manager.test.ts new file mode 100644 index 00000000..ab99d66e --- /dev/null +++ b/src/test/cloudflare/services/api-shield-manager.test.ts @@ -0,0 +1,287 @@ +import { + ApiShield, + ApiShieldOperation, + ApiShieldOperationSchemaValidationSettings, + ApiShieldSchema, + ApiShieldSchemaValidationSettings, + Zone, +} from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import fs from 'fs' +import { + ApiShieldOperationProps, + ApiShieldOperationSchemaValidationSettingsProps, + ApiShieldProps, + ApiShieldSchemaProps, + ApiShieldSchemaValidationSettingsProps, + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testApiShield: ApiShieldProps + testApiShieldSchema: ApiShieldSchemaProps + testApiShieldSchemaValidationSettings: ApiShieldSchemaValidationSettingsProps + testApiShieldOperation: ApiShieldOperationProps + testApiShieldOperationSchemaValidationSettings: ApiShieldOperationSchemaValidationSettingsProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/cdkConfig/api-shield.json', + 'src/test/cloudflare/common/cdkConfig/dummy.json', + 'src/test/cloudflare/common/cdkConfig/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testApiShield: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + apiShield: ApiShield + apiShieldSchema: ApiShieldSchema + apiShieldSchemaValidationSettings: ApiShieldSchemaValidationSettings + apiShieldOperation: ApiShieldOperation + apiShieldOperationSchemaValidationSettings: ApiShieldOperationSchemaValidationSettings + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { + zoneId: this.zone.id, + }) + this.apiShield = this.apiShieldManager.createApiShield( + `test-api-shield-${this.props.stage}`, + this, + this.props.testApiShield + ) + this.apiShieldSchema = this.apiShieldManager.createApiShieldSchema( + `test-api-shield-sch-${this.props.stage}`, + this, + { + ...this.props.testApiShieldSchema, + file: fs.readFileSync('src/test/cloudflare/common/sample.json', { encoding: 'utf8' }), + } + ) + this.apiShieldSchemaValidationSettings = this.apiShieldManager.createApiShieldSchemaValidationSettings( + `test-api-shield-val-${this.props.stage}`, + this, + this.props.testApiShieldSchemaValidationSettings + ) + this.apiShieldOperation = this.apiShieldManager.createApiShieldOperation( + `test-api-shield-op-${this.props.stage}`, + this, + this.props.testApiShieldOperation + ) + this.apiShieldOperationSchemaValidationSettings = + this.apiShieldManager.createApiShieldOperationSchemaValidationSettings( + `test-api-shield-op-val-${this.props.stage}`, + this, + { + ...this.props.testApiShieldOperationSchemaValidationSettings, + operationId: this.apiShieldOperation.id, + } + ) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareApiShieldManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareApiShieldManager', () => { + test('is initialised as expected', () => { + /* test if the created stack have the right properties injected */ + expect(stack.props).toHaveProperty('testAttribute') + expect(stack.props.testAttribute).toEqual('success') + pulumi.all([stack.urn]).apply(([urn]) => { + expect(urn).toEqual('urn:pulumi:stack::project::custom:cloudflare:Stack:test-stack::test-stack') + }) + }) +}) + +describe('TestCloudflareApiShieldManager', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareApiShieldManager', () => { + expect(stack.construct.apiShield).toBeDefined() + test('provisions api shield as expected', () => { + pulumi + .all([ + stack.construct.apiShield.id, + stack.construct.apiShield.urn, + stack.construct.apiShield.authIdCharacteristics, + stack.construct.apiShield.zoneId, + ]) + .apply(([id, urn, authIdCharacteristics, zoneId]) => { + expect(id).toEqual('test-api-shield-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/apiShield:ApiShield::test-api-shield-dev') + expect(authIdCharacteristics).toEqual([ + { + name: 'test-api-shield', + type: 'header', + }, + ]) + expect(zoneId).toEqual('test-api-shield-dev-data-zone') + }) + }) +}) + +describe('TestCloudflareApiShieldManager', () => { + expect(stack.construct.apiShieldSchema).toBeDefined() + test('provisions api shield schema as expected', () => { + pulumi + .all([ + stack.construct.apiShieldSchema.id, + stack.construct.apiShieldSchema.urn, + stack.construct.apiShieldSchema.file, + stack.construct.apiShieldSchema.kind, + stack.construct.apiShieldSchema.name, + stack.construct.apiShieldSchema.zoneId, + ]) + .apply(([id, urn, file, kind, name, zoneId]) => { + expect(id).toEqual('test-api-shield-sch-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/apiShieldSchema:ApiShieldSchema::test-api-shield-sch-dev' + ) + expect(file).toEqual('{\n "test": true,\n "hello": "world"\n}\n') + expect(kind).toEqual('openapi_v3') + expect(name).toEqual('test-api-dev') + expect(zoneId).toEqual('test-api-shield-sch-dev-data-zone') + }) + }) +}) + +describe('TestCloudflareApiShieldManager', () => { + expect(stack.construct.apiShieldSchemaValidationSettings).toBeDefined() + test('provisions api shield schema validation settings as expected', () => { + pulumi + .all([ + stack.construct.apiShieldSchemaValidationSettings.id, + stack.construct.apiShieldSchemaValidationSettings.urn, + stack.construct.apiShieldSchemaValidationSettings.validationDefaultMitigationAction, + stack.construct.apiShieldSchemaValidationSettings.validationOverrideMitigationAction, + stack.construct.apiShieldSchemaValidationSettings.zoneId, + ]) + .apply(([id, urn, validationDefaultMitigationAction, validationOverrideMitigationAction, zoneId]) => { + expect(id).toEqual('test-api-shield-val-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/apiShieldSchemaValidationSettings:ApiShieldSchemaValidationSettings::test-api-shield-val-dev' + ) + expect(validationDefaultMitigationAction).toEqual('log') + expect(validationOverrideMitigationAction).toEqual('none') + expect(zoneId).toEqual('test-api-shield-val-dev-data-zone') + }) + }) +}) + +describe('TestCloudflareApiShieldManager', () => { + expect(stack.construct.apiShieldOperation).toBeDefined() + test('provisions api shield operation as expected', () => { + pulumi + .all([ + stack.construct.apiShieldOperation.id, + stack.construct.apiShieldOperation.urn, + stack.construct.apiShieldOperation.endpoint, + stack.construct.apiShieldOperation.host, + stack.construct.apiShieldOperation.method, + stack.construct.apiShieldOperation.zoneId, + ]) + .apply(([id, urn, endpoint, host, method, zoneId]) => { + expect(id).toEqual('test-api-shield-op-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/apiShieldOperation:ApiShieldOperation::test-api-shield-op-dev' + ) + expect(endpoint).toEqual('/product') + expect(host).toEqual('api.gradientedge.io') + expect(method).toEqual('GET') + expect(zoneId).toEqual('test-api-shield-op-dev-data-zone') + }) + }) +}) + +describe('TestCloudflareApiShieldManager', () => { + expect(stack.construct.apiShieldOperationSchemaValidationSettings).toBeDefined() + test('provisions api shield operation schema validation settings as expected', () => { + pulumi + .all([ + stack.construct.apiShieldOperationSchemaValidationSettings.id, + stack.construct.apiShieldOperationSchemaValidationSettings.urn, + stack.construct.apiShieldOperationSchemaValidationSettings.mitigationAction, + stack.construct.apiShieldOperationSchemaValidationSettings.operationId, + stack.construct.apiShieldOperationSchemaValidationSettings.zoneId, + ]) + .apply(([id, urn, mitigationAction, operationId, zoneId]) => { + expect(id).toEqual('test-api-shield-op-val-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/apiShieldOperationSchemaValidationSettings:ApiShieldOperationSchemaValidationSettings::test-api-shield-op-val-dev' + ) + expect(mitigationAction).toEqual('block') + expect(operationId).toEqual('test-api-shield-op-dev-id') + expect(zoneId).toEqual('test-api-shield-op-val-dev-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/services/api-shield-manager.test.ts1 b/src/test/cloudflare/services/api-shield-manager.test.ts1 deleted file mode 100644 index 13a8f46d..00000000 --- a/src/test/cloudflare/services/api-shield-manager.test.ts1 +++ /dev/null @@ -1,260 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import fs from 'fs' -import { - ApiShieldOperationProps, - ApiShieldOperationSchemaValidationSettingsProps, - ApiShieldProps, - ApiShieldSchemaProps, - ApiShieldSchemaValidationSettingsProps, - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testApiShield: ApiShieldProps - testApiShieldSchema: ApiShieldSchemaProps - testApiShieldSchemaValidationSettings: ApiShieldSchemaValidationSettingsProps - testApiShieldOperation: ApiShieldOperationProps - testApiShieldOperationSchemaValidationSettings: ApiShieldOperationSchemaValidationSettingsProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/api-shield.json', - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testApiShield: this.node.tryGetContext('testApiShield'), - testApiShieldOperation: this.node.tryGetContext('testApiShieldOperation'), - testApiShieldOperationSchemaValidationSettings: this.node.tryGetContext( - 'testApiShieldOperationSchemaValidationSettings' - ), - testApiShieldSchema: this.node.tryGetContext('testApiShieldSchema'), - testApiShieldSchemaValidationSettings: this.node.tryGetContext('testApiShieldSchemaValidationSettings'), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testApiShieldOperation: this.node.tryGetContext('testApiShieldOperation'), - testApiShieldOperationSchemaValidationSettings: this.node.tryGetContext( - 'testApiShieldOperationSchemaValidationSettings' - ), - testApiShieldSchema: this.node.tryGetContext('testApiShieldSchema'), - testApiShieldSchemaValidationSettings: this.node.tryGetContext('testApiShieldSchemaValidationSettings'), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - const zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { - zoneId: zone.id, - }) - this.apiShieldManager.createApiShield(`test-api-shield-${this.props.stage}`, this, this.props.testApiShield) - this.apiShieldManager.createApiShieldSchema(`test-api-shield-sch-${this.props.stage}`, this, { - ...this.props.testApiShieldSchema, - file: fs.readFileSync('src/test/cloudflare/common/sample.json', { encoding: 'utf8' }), - }) - this.apiShieldManager.createApiShieldSchemaValidationSettings( - `test-api-shield-val-${this.props.stage}`, - this, - this.props.testApiShieldSchemaValidationSettings - ) - const apiOperation = this.apiShieldManager.createApiShieldOperation( - `test-api-shield-op-${this.props.stage}`, - this, - this.props.testApiShieldOperation - ) - this.apiShieldManager.createApiShieldOperationSchemaValidationSettings( - `test-api-shield-op-val-${this.props.stage}`, - this, - { - ...this.props.testApiShieldOperationSchemaValidationSettings, - operationId: apiOperation.id, - } - ) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareApiShieldManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-api-shield-dev') - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testApiShieldDevApiShieldFriendlyUniqueId: { value: 'test-api-shield-dev' }, - testApiShieldDevApiShieldId: { value: '${cloudflare_api_shield.test-api-shield-dev.id}' }, - testApiShieldOpDevApiShieldOperationFriendlyUniqueId: { value: 'test-api-shield-op-dev' }, - testApiShieldOpDevApiShieldOperationId: { - value: '${cloudflare_api_shield_operation.test-api-shield-op-dev.id}', - }, - testApiShieldOpValDevApiShieldOperationSchemaValidationSettingsFriendlyUniqueId: { - value: 'test-api-shield-op-val-dev', - }, - testApiShieldOpValDevApiShieldOperationSchemaValidationSettingsId: { - value: '${cloudflare_api_shield_operation_schema_validation_settings.test-api-shield-op-val-dev.id}', - }, - testApiShieldSchDevApiShieldSchemaFriendlyUniqueId: { value: 'test-api-shield-sch-dev' }, - testApiShieldSchDevApiShieldSchemaId: { - value: '${cloudflare_api_shield_schema.test-api-shield-sch-dev.schema_id}', - }, - testApiShieldValDevApiShieldSchemaValidationSettingsFriendlyUniqueId: { value: 'test-api-shield-val-dev' }, - testApiShieldValDevApiShieldSchemaValidationSettingsId: { - value: '${cloudflare_api_shield_schema_validation_settings.test-api-shield-val-dev.id}', - }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - }) - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('provisions api shield as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ApiShield', { - auth_id_characteristics: [ - { - name: 'test-api-shield', - type: 'header', - }, - ], - zone_id: '${data.cloudflare_zone.test-api-shield-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('provisions api shield schema as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ApiShieldSchema', { - file: '{\n "test": true,\n "hello": "world"\n}\n', - kind: 'openapi_v3', - name: 'test-api-dev', - zone_id: '${data.cloudflare_zone.test-api-shield-sch-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('provisions api shield schema validation settings as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ApiShieldSchemaValidationSettings', { - validation_default_mitigation_action: 'log', - validation_override_mitigation_action: 'none', - zone_id: '${data.cloudflare_zone.test-api-shield-val-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('provisions api shield operation as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ApiShieldOperation', { - endpoint: '/product', - host: 'api.gradientedge.io', - method: 'GET', - zone_id: '${data.cloudflare_zone.test-api-shield-op-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareApiShieldManager', () => { - test('provisions api shield operation schema validation settings as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ApiShieldOperationSchemaValidationSettings', { - mitigation_action: 'block', - operation_id: '${cloudflare_api_shield_operation.test-api-shield-op-dev.id}', - zone_id: '${data.cloudflare_zone.test-api-shield-op-val-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/argo-manager.test.ts b/src/test/cloudflare/services/argo-manager.test.ts new file mode 100644 index 00000000..dc73bd77 --- /dev/null +++ b/src/test/cloudflare/services/argo-manager.test.ts @@ -0,0 +1,128 @@ +import { ArgoSmartRouting, Zone } from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import { + ArgoSmartRoutingProps, + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testArgo: ArgoSmartRoutingProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/cdkConfig/dummy.json', + 'src/test/cloudflare/common/cdkConfig/argo.json', + 'src/test/cloudflare/common/cdkConfig/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testArgo: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + argoSmartRouting: ArgoSmartRouting + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { + zoneId: this.zone.id, + }) + this.argoSmartRouting = this.argoManager.createArgoSmartRouting( + `test-argo-${this.props.stage}`, + this, + this.props.testArgo + ) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareArgoManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareArgoManager', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareArgoManager', () => { + expect(stack.construct.argoSmartRouting).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([ + stack.construct.argoSmartRouting.id, + stack.construct.argoSmartRouting.urn, + stack.construct.argoSmartRouting.value, + ]) + .apply(([id, urn, value]) => { + expect(id).toEqual('test-argo-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/argoSmartRouting:ArgoSmartRouting::test-argo-dev' + ) + expect(value).toEqual('on') + }) + }) +}) diff --git a/src/test/cloudflare/services/argo-manager.test.ts1 b/src/test/cloudflare/services/argo-manager.test.ts1 deleted file mode 100644 index 68844527..00000000 --- a/src/test/cloudflare/services/argo-manager.test.ts1 +++ /dev/null @@ -1,145 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - ArgoSmartRoutingProps, - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testArgo: ArgoSmartRoutingProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/argo.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testArgo: this.node.tryGetContext('testArgo'), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - const zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { - zoneId: zone.id, - }) - const filter = this.argoManager.createArgoSmartRouting(`test-argo-${this.props.stage}`, this, this.props.testArgo) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareArgoManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-argo-dev') - }) -}) - -describe('TestCloudflareArgoManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareArgoManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareArgoManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testZoneCacheReserveDevZoneCacheReserveFriendlyUniqueId: { value: 'test-zone-cache-reserve-dev' }, - testZoneCacheReserveDevZoneCacheReserveId: { - value: '${cloudflare_zone_cache_reserve.test-zone-cache-reserve-dev.id}', - }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - }) - }) -}) - -describe('TestCloudflareArgoManager', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareArgoManager', () => { - test('provisions argo as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ArgoSmartRouting', { - zone_id: '${data.cloudflare_zone.test-argo-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/firewall-manager.test.ts b/src/test/cloudflare/services/firewall-manager.test.ts new file mode 100644 index 00000000..44b1a91b --- /dev/null +++ b/src/test/cloudflare/services/firewall-manager.test.ts @@ -0,0 +1,168 @@ +import { Filter, FirewallRule, Zone } from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import { + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + FilterProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' +import { FirewallRuleProps } from '../../../lib/cloudflare/services/firewall/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testFilter: FilterProps + testFirewallRule: FirewallRuleProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/cdkConfig/dummy.json', + 'src/test/cloudflare/common/cdkConfig/filter.json', + 'src/test/cloudflare/common/cdkConfig/firewall.json', + 'src/test/cloudflare/common/cdkConfig/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testFilter: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + filter: Filter + firewallRule: FirewallRule + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { + zoneId: this.zone.id, + }) + this.filter = this.filterManager.createFilter(`test-filter-${this.props.stage}`, this, this.props.testFilter) + this.firewallRule = this.firewallManager.createFirewallRule(`test-firewall-rule-${this.props.stage}`, this, { + ...this.props.testFirewallRule, + filter: this.props.testFilter, + }) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareFirewallManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareFirewallManager', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareFirewallManager', () => { + expect(stack.construct.filter).toBeDefined() + test('provisions filter as expected', () => { + pulumi + .all([ + stack.construct.filter.id, + stack.construct.filter.urn, + stack.construct.filter.bodies, + stack.construct.filter.expression, + ]) + .apply(([id, urn, bodies, expression]) => { + expect(id).toEqual('test-filter-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/filter:Filter::test-filter-dev') + expect(bodies).toEqual([ + { + description: 'Site break-in attempts that are outside of the office', + expression: + '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.src ne 192.0.2.1', + paused: false, + }, + ]) + }) + }) +}) + +describe('TestCloudflareFirewallManager', () => { + expect(stack.construct.filter).toBeDefined() + test('provisions firewall rule as expected', () => { + pulumi + .all([ + stack.construct.firewallRule.id, + stack.construct.firewallRule.urn, + stack.construct.firewallRule.filter, + stack.construct.firewallRule.zoneId, + ]) + .apply(([id, urn, filter, zoneId]) => { + expect(id).toEqual('test-firewall-rule-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/firewallRule:FirewallRule::test-firewall-rule-dev' + ) + expect(filter).toEqual({ + bodies: [ + { + description: 'Site break-in attempts that are outside of the office', + expression: + '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.src ne 192.0.2.1', + paused: false, + }, + ], + }) + expect(zoneId).toEqual('test-firewall-rule-dev-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/services/firewall-manager.test.ts1 b/src/test/cloudflare/services/firewall-manager.test.ts1 deleted file mode 100644 index bdbf13df..00000000 --- a/src/test/cloudflare/services/firewall-manager.test.ts1 +++ /dev/null @@ -1,174 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - FilterProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' -import { FirewallRuleProps } from '../../../lib/cloudflare/services/firewall/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testFilter: FilterProps - testFirewallRule: FirewallRuleProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/filter.json', - 'src/test/cloudflare/common/cdkConfig/firewall.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testFilter: this.node.tryGetContext('testFilter'), - testFirewallRule: this.node.tryGetContext('testFirewallRule'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testFirewallRule: this.node.tryGetContext('testFirewallRule'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - const zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { - zoneId: zone.id, - }) - const filter = this.filterManager.createApiShield(`test-filter-${this.props.stage}`, this, this.props.testFilter) - this.firewallManager.createFirewallRule(`test-firewall-rule-${this.props.stage}`, this, { - ...this.props.testFirewallRule, - filter: { - ...this.props.testFilter, - }, - }) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareFirewallManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-filter-dev') - }) -}) - -describe('TestCloudflareFirewallManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareFirewallManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareFirewallManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testFilterDevFilterFriendlyUniqueId: { value: 'test-filter-dev' }, - testFilterDevFilterId: { value: '${cloudflare_filter.test-filter-dev.id}' }, - testFirewallRuleDevFirewallRuleFriendlyUniqueId: { value: 'test-firewall-rule-dev' }, - testFirewallRuleDevFirewallRuleId: { value: '${cloudflare_firewall_rule.test-firewall-rule-dev.id}' }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - }) - }) -}) - -describe('TestCloudflareFirewallManager', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareFirewallManager', () => { - test('provisions filter as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Filter', { - expression: - '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.src ne 192.0.2.1', - zone_id: '${data.cloudflare_zone.test-filter-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareFirewallManager', () => { - test('provisions firewall rule as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'FirewallRule', { - filter: { - description: 'Site break-in attempts that are outside of the office', - expression: - '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.src ne 192.0.2.1', - paused: false, - }, - zone_id: '${data.cloudflare_zone.test-firewall-rule-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/page-manager.test.ts b/src/test/cloudflare/services/page-manager.test.ts new file mode 100644 index 00000000..b7e3713f --- /dev/null +++ b/src/test/cloudflare/services/page-manager.test.ts @@ -0,0 +1,234 @@ +import { PageRule, PagesDomain, PagesProject } from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import { + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + PageRuleProps, + PagesDomainProps, + PagesProjectProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testPagesProject: PagesProjectProps + testPagesProjectBuildConfig: PagesProjectProps + testPagesDomain: PagesDomainProps + testPageRule: PageRuleProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: ['src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/pages.json'], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testPageRule: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + pagesProject: PagesProject + pagesProjectWithBuild: PagesProject + pagesDomain: PagesDomain + pageRule: PageRule + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.pagesProject = this.pageManager.createPagesProject( + `test-pages-project-${this.props.stage}`, + this, + this.props.testPagesProject + ) + this.pagesProjectWithBuild = this.pageManager.createPagesProject( + `test-pages-project-with-build-${this.props.stage}`, + this, + this.props.testPagesProjectBuildConfig + ) + this.pagesDomain = this.pageManager.createPagesDomain(`test-pages-domain-${this.props.stage}`, this, { + ...this.props.testPagesDomain, + projectName: `test-pages-project-${this.props.stage}`, + }) + this.pageRule = this.pageManager.createPageRule(`test-page-rule-${this.props.stage}`, this, this.props.testPageRule) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflarePagesManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflarePagesManager', () => { + expect(stack.construct.pagesProject).toBeDefined() + test('provisions pages project as expected', () => { + pulumi + .all([ + stack.construct.pagesProject.id, + stack.construct.pagesProject.urn, + stack.construct.pagesProject.accountId, + stack.construct.pagesProject.name, + stack.construct.pagesProject.productionBranch, + ]) + .apply(([id, urn, accountId, name, productionBranch]) => { + expect(id).toEqual('test-pages-project-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/pagesProject:PagesProject::test-pages-project-dev' + ) + expect(accountId).toEqual('123456789012') + expect(name).toEqual('test-simple-project-dev') + expect(productionBranch).toEqual('main') + }) + }) + + expect(stack.construct.pagesProjectWithBuild).toBeDefined() + test('provisions pages project as expected', () => { + pulumi + .all([ + stack.construct.pagesProjectWithBuild.id, + stack.construct.pagesProjectWithBuild.urn, + stack.construct.pagesProjectWithBuild.accountId, + stack.construct.pagesProjectWithBuild.name, + stack.construct.pagesProjectWithBuild.productionBranch, + stack.construct.pagesProjectWithBuild.buildConfig, + stack.construct.pagesProjectWithBuild.deploymentConfigs, + ]) + .apply(([id, urn, accountId, name, productionBranch, buildConfig, deploymentConfigs]) => { + expect(id).toEqual('test-pages-project-with-build-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/pagesProject:PagesProject::test-pages-project-with-build-dev' + ) + expect(accountId).toEqual('123456789012') + expect(name).toEqual('test-build-config-project-dev') + expect(productionBranch).toEqual('main') + expect(buildConfig).toEqual({ + buildCommand: 'npm run build', + destinationDir: 'dist', + rootDir: '', + }) + expect(deploymentConfigs).toEqual({ + preview: { + compatibility_date: '2023-11-23', + compatibility_flags: ['nodejs_compat'], + envVars: { + TEST_ENV_VAR: { + type: 'plain_text', + value: 'preview', + }, + TEST_SECRET: { + type: 'secret_text', + value: '0987654321', + }, + }, + }, + production: { + compatibility_date: '2023-11-23', + compatibility_flags: ['nodejs_compat'], + envVars: { + TEST_ENV_VAR: { + type: 'plain_text', + value: 'production', + }, + TEST_SECRET: { + type: 'secret_text', + value: '1234567890', + }, + }, + }, + }) + }) + }) +}) + +describe('TestCloudflarePagesManager', () => { + expect(stack.construct.pagesDomain).toBeDefined() + test('provisions pages domain as expected', () => { + pulumi + .all([ + stack.construct.pagesDomain.id, + stack.construct.pagesDomain.urn, + stack.construct.pagesDomain.accountId, + stack.construct.pagesDomain.name, + stack.construct.pagesDomain.projectName, + ]) + .apply(([id, urn, accountId, name, projectName]) => { + expect(id).toEqual('test-pages-domain-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/pagesDomain:PagesDomain::test-pages-domain-dev' + ) + expect(accountId).toEqual('123456789012') + expect(name).toEqual('gradientedge.io') + expect(projectName).toEqual('test-pages-project-dev') + }) + }) +}) + +describe('TestCloudflarePagesManager', () => { + expect(stack.construct.pageRule).toBeDefined() + test('provisions page rule as expected', () => { + pulumi + .all([ + stack.construct.pageRule.id, + stack.construct.pageRule.urn, + stack.construct.pageRule.actions, + stack.construct.pageRule.priority, + stack.construct.pageRule.target, + stack.construct.pageRule.zoneId, + ]) + .apply(([id, urn, actions, priority, target, zoneId]) => { + expect(id).toEqual('test-page-rule-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/pageRule:PageRule::test-page-rule-dev') + expect(actions).toEqual({ + emailObfuscation: 'on', + ssl: 'flexible', + }) + expect(priority).toEqual(1) + expect(target).toEqual('test.gradientedge.io/p/*') + expect(zoneId).toEqual('test-page-rule-dev-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/services/page-manager.test.ts1 b/src/test/cloudflare/services/page-manager.test.ts1 deleted file mode 100644 index d4ae6a38..00000000 --- a/src/test/cloudflare/services/page-manager.test.ts1 +++ /dev/null @@ -1,214 +0,0 @@ -import { PageRule } from '@cdktf/provider-cloudflare/lib/page-rule/index.js' -import { PagesDomain } from '@cdktf/provider-cloudflare/lib/pages-domain/index.js' -import { PagesProject } from '@cdktf/provider-cloudflare/lib/pages-project/index.js' -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - PageRuleProps, - PagesDomainProps, - PagesProjectProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testPagesProject: PagesProjectProps - testPagesProjectBuildConfig: PagesProjectProps - testPagesDomain: PagesDomainProps - testPageRule: PageRuleProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: ['src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/pages.json'], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testPageRule: this.node.tryGetContext('testPageRule'), - testPagesDomain: this.node.tryGetContext('testPagesDomain'), - testPagesProject: this.node.tryGetContext('testPagesProject'), - testPagesProjectBuildConfig: this.node.tryGetContext('testPagesProjectBuildConfig'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - this.pageManager.createPagesProject(`test-pages-project-${this.props.stage}`, this, this.props.testPagesProject) - this.pageManager.createPagesProject( - `test-pages-project-with-build-${this.props.stage}`, - this, - this.props.testPagesProjectBuildConfig - ) - this.pageManager.createPagesDomain(`test-pages-domain-${this.props.stage}`, this, { - ...this.props.testPagesDomain, - projectName: `test-pages-project-${this.props.stage}`, - }) - this.pageManager.createPageRule(`test-page-rule-${this.props.stage}`, this, this.props.testPageRule) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflarePagesManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-pages-project-dev') - }) -}) - -describe('TestCloudflarePagesManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflarePagesManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflarePagesManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testPageRuleDevPageRuleFriendlyUniqueId: { value: 'test-page-rule-dev' }, - testPageRuleDevPageRuleId: { value: '${cloudflare_page_rule.test-page-rule-dev.id}' }, - testPagesDomainDevPagesDomainFriendlyUniqueId: { value: 'test-pages-domain-dev' }, - testPagesDomainDevPagesDomainId: { value: '${cloudflare_pages_domain.test-pages-domain-dev.id}' }, - testPagesProjectDevPagesProjectFriendlyUniqueId: { value: 'test-pages-project-dev' }, - testPagesProjectDevPagesProjectId: { value: '${cloudflare_pages_project.test-pages-project-dev.id}' }, - testPagesProjectWithBuildDevPagesProjectFriendlyUniqueId: { value: 'test-pages-project-with-build-dev' }, - testPagesProjectWithBuildDevPagesProjectId: { - value: '${cloudflare_pages_project.test-pages-project-with-build-dev.id}', - }, - }) - }) -}) - -describe('TestCloudflarePagesManager', () => { - test('provisions pages project as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'PagesProject', { - account_id: '${var.accountId}', - name: 'test-simple-project-dev', - production_branch: 'main', - }) - ) - expect( - Testing.toHaveResourceWithProperties(construct, 'PagesProject', { - account_id: '${var.accountId}', - build_config: { - build_command: 'npm run build', - destination_dir: 'dist', - root_dir: '', - }, - deployment_configs: { - preview: { - env_vars: { - TEST_ENV_VAR: { - type: 'plain_text', - value: 'preview', - }, - TEST_SECRET: { - type: 'secret_text', - value: '0987654321', - }, - }, - }, - production: { - env_vars: { - TEST_ENV_VAR: { - type: 'plain_text', - value: 'production', - }, - TEST_SECRET: { - type: 'secret_text', - value: '1234567890', - }, - }, - }, - }, - name: 'test-build-config-project-dev', - production_branch: 'main', - }) - ) - }) -}) - -describe('TestCloudflarePagesManager', () => { - test('provisions pages domain as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'PagesDomain', { - account_id: '${var.accountId}', - name: 'gradientedge.io', - project_name: 'test-pages-project-dev', - }) - ) - }) -}) - -describe('TestCloudflarePagesManager', () => { - test('provisions page rule as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'PageRule', { - actions: { - email_obfuscation: 'on', - ssl: 'flexible', - }, - priority: 1, - target: 'test.gradientedge.io/p/*', - zone_id: '${data.cloudflare_zone.test-page-rule-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/record-manager.test.ts b/src/test/cloudflare/services/record-manager.test.ts new file mode 100644 index 00000000..d4f356a2 --- /dev/null +++ b/src/test/cloudflare/services/record-manager.test.ts @@ -0,0 +1,157 @@ +import { DnsRecord, Zone } from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import { + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + DnsRecordProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testARecord: DnsRecordProps + testCNameRecord: DnsRecordProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/cdkConfig/dummy.json', + 'src/test/cloudflare/common/cdkConfig/record.json', + 'src/test/cloudflare/common/cdkConfig/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testARecord: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + aRecord: DnsRecord + cnameRecord: DnsRecord + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.aRecord = this.recordManager.createRecord(`test-arecord-${this.props.stage}`, this, this.props.testARecord) + this.cnameRecord = this.recordManager.createRecord( + `test-cnamerecord-${this.props.stage}`, + this, + this.props.testCNameRecord + ) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareRecordManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareRecordManager', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareRecordManager', () => { + expect(stack.construct.aRecord).toBeDefined() + test('provisions A record as expected', () => { + pulumi + .all([ + stack.construct.aRecord.id, + stack.construct.aRecord.urn, + stack.construct.aRecord.name, + stack.construct.aRecord.ttl, + stack.construct.aRecord.type, + stack.construct.aRecord.content, + stack.construct.aRecord.zoneId, + ]) + .apply(([id, urn, name, ttl, type, content, zoneId]) => { + expect(id).toEqual('test-arecord-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/dnsRecord:DnsRecord::test-arecord-dev') + expect(name).toEqual('testARecord') + expect(ttl).toEqual(300) + expect(type).toEqual('A') + expect(content).toEqual('192.0.2.1') + expect(zoneId).toEqual('test-arecord-dev-data-zone') + }) + }) + + expect(stack.construct.cnameRecord).toBeDefined() + test('provisions CNAME record as expected', () => { + pulumi + .all([ + stack.construct.cnameRecord.id, + stack.construct.cnameRecord.urn, + stack.construct.cnameRecord.name, + stack.construct.cnameRecord.ttl, + stack.construct.cnameRecord.type, + stack.construct.cnameRecord.content, + stack.construct.cnameRecord.zoneId, + ]) + .apply(([id, urn, name, ttl, type, content, zoneId]) => { + expect(id).toEqual('test-cnamerecord-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/dnsRecord:DnsRecord::test-cnamerecord-dev') + expect(name).toEqual('testCNameRecord') + expect(ttl).toEqual(300) + expect(type).toEqual('CNAME') + expect(content).toEqual('example.gradientedge.io') + expect(zoneId).toEqual('test-cnamerecord-dev-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/services/record-manager.test.ts1 b/src/test/cloudflare/services/record-manager.test.ts1 deleted file mode 100644 index 7747024b..00000000 --- a/src/test/cloudflare/services/record-manager.test.ts1 +++ /dev/null @@ -1,158 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - DnsRecordProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testARecord: DnsRecordProps - testCNameRecord: DnsRecordProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/record.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testARecord: this.node.tryGetContext('testARecord'), - testAttribute: this.node.tryGetContext('testAttribute'), - testCNameRecord: this.node.tryGetContext('testCNameRecord'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.recordManager.createRecord(`test-arecord-${this.props.stage}`, this, this.props.testARecord) - this.recordManager.createRecord(`test-cnamerecord-${this.props.stage}`, this, this.props.testCNameRecord) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareRecordManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-arecord-dev') - }) -}) - -describe('TestCloudflareRecordManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareRecordManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareRecordManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testArecordDevRecordFriendlyUniqueId: { value: 'test-arecord-dev' }, - testArecordDevRecordId: { value: '${cloudflare_dns_record.test-arecord-dev.id}' }, - testCnamerecordDevRecordFriendlyUniqueId: { value: 'test-cnamerecord-dev' }, - testCnamerecordDevRecordId: { value: '${cloudflare_dns_record.test-cnamerecord-dev.id}' }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - }) - }) -}) - -describe('TestCloudflareRecordManager', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareRecordManager', () => { - test('provisions ARecord as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'DnsRecord', { - name: 'testARecord', - ttl: 300, - type: 'A', - content: '192.0.2.1', - zone_id: '${data.cloudflare_zone.test-arecord-dev-data-zone-data-zone.zone_id}', - }) - ) - expect( - Testing.toHaveResourceWithProperties(construct, 'DnsRecord', { - name: 'testCNameRecord', - ttl: 300, - type: 'CNAME', - content: 'example.gradientedge.io', - zone_id: '${data.cloudflare_zone.test-cnamerecord-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/rule-set-manager.test.ts b/src/test/cloudflare/services/rule-set-manager.test.ts new file mode 100644 index 00000000..0d0da032 --- /dev/null +++ b/src/test/cloudflare/services/rule-set-manager.test.ts @@ -0,0 +1,123 @@ +import { Ruleset, Zone } from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import { + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + RulesetProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testRuleSet: RulesetProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/cdkConfig/dummy.json', + 'src/test/cloudflare/common/cdkConfig/rule-set.json', + 'src/test/cloudflare/common/cdkConfig/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testRuleSet: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + ruleSet: Ruleset + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.ruleSet = this.ruleSetManager.createRuleSet(`test-rule-set-${this.props.stage}`, this, this.props.testRuleSet) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareRuleSetManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareRuleSetManager', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareRuleSetManager', () => { + expect(stack.construct.ruleSet).toBeDefined() + test('provisions ruleset as expected', () => { + pulumi + .all([ + stack.construct.ruleSet.id, + stack.construct.ruleSet.urn, + stack.construct.ruleSet.name, + stack.construct.ruleSet.rules, + ]) + .apply(([id, urn, name, rules]) => { + expect(id).toEqual('test-rule-set-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/ruleset:Ruleset::test-rule-set-dev') + expect(name).toEqual('testRuleSet') + expect(rules).toEqual({ + action: 'set_cache_settings', + }) + }) + }) +}) diff --git a/src/test/cloudflare/services/rule-set-manager.test.ts1 b/src/test/cloudflare/services/rule-set-manager.test.ts1 deleted file mode 100644 index 36e1c773..00000000 --- a/src/test/cloudflare/services/rule-set-manager.test.ts1 +++ /dev/null @@ -1,143 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - RulesetProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testRuleSet: RulesetProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/rule-set.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testRuleSet: this.node.tryGetContext('testRuleSet'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.ruleSetManager.createRuleSet(`test-rule-set-${this.props.stage}`, this, this.props.testRuleSet) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareRuleSetManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-rule-set-dev') - }) -}) - -describe('TestCloudflareRuleSetManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareRuleSetManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareRuleSetManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testRuleSetDevRuleSetFriendlyUniqueId: { value: 'test-rule-set-dev' }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - }) - }) -}) - -describe('TestCloudflareRuleSetManager', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareRuleSetManager', () => { - test('provisions Rule Set as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Ruleset', { - name: 'testRuleSet', - zone_id: '${data.cloudflare_zone.test-rule-set-dev-data-zone-data-zone.zone_id}', - rules: { - action: 'set_cache_settings', - }, - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/worker-manager.test.ts b/src/test/cloudflare/services/worker-manager.test.ts new file mode 100644 index 00000000..e7023b63 --- /dev/null +++ b/src/test/cloudflare/services/worker-manager.test.ts @@ -0,0 +1,187 @@ +import { + WorkersCronTrigger, + WorkersCustomDomain, + WorkersKv, + WorkersKvNamespace, + WorkersRoute, + WorkersScript, + Zone, + ZoneCacheReserve, +} from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import fs from 'fs' +import { + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + WorkerCronTriggerProps, + WorkerDomainProps, + WorkerRouteProps, + WorkerScriptProps, + WorkersKvNamespaceProps, + WorkersKvProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testWorkerDomain: WorkerDomainProps + testWorkerRoute: WorkerRouteProps + testWorkerScript: WorkerScriptProps + testWorkersKvNamespace: WorkersKvNamespaceProps + testWorkersKv: WorkersKvProps + testWorkerCronTrigger: WorkerCronTriggerProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/cdkConfig/dummy.json', + 'src/test/cloudflare/common/cdkConfig/worker.json', + 'src/test/cloudflare/common/cdkConfig/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testWorkerCronTrigger: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + zoneCacheReserve: ZoneCacheReserve + workersCustomDomain: WorkersCustomDomain + workersRoute: WorkersRoute + workersScript: WorkersScript + workersKvNamespace: WorkersKvNamespace + workersKv: WorkersKv + workersCronTrigger: WorkersCronTrigger + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.zoneCacheReserve = this.zoneManager.createZoneCacheReserve( + `test-zone-cache-reserve-${this.props.stage}`, + this, + { + zoneId: this.zone.id, + } + ) + this.workersCustomDomain = this.workerManager.createWorkerDomain( + `test-worker-domain-${this.props.stage}`, + this, + this.props.testWorkerDomain + ) + this.workersRoute = this.workerManager.createWorkerRoute( + `test-worker-route-${this.props.stage}`, + this, + this.props.testWorkerRoute + ) + this.workersScript = this.workerManager.createWorkerScript(`test-worker-script-${this.props.stage}`, this, { + ...this.props.testWorkerScript, + content: fs.readFileSync('src/test/cloudflare/common/sample.js', { encoding: 'utf8' }), + }) + this.workersKvNamespace = this.workerManager.createWorkersKvNamespace( + `test-workers-kv-ns-${this.props.stage}`, + this, + this.props.testWorkersKvNamespace + ) + this.workersKv = this.workerManager.createWorkersKv(`test-workers-kv-${this.props.stage}`, this, { + ...this.props.testWorkersKv, + namespaceId: this.workersKvNamespace.id, + }) + this.workersCronTrigger = this.workerManager.createWorkerCronTrigger( + `test-worker-trigger-${this.props.stage}`, + this, + this.props.testWorkerCronTrigger + ) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareWorkerManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareWorkerManager', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareWorkerManager', () => { + expect(stack.construct.workersCustomDomain).toBeDefined() + test('provisions workers custom domain as expected', () => { + pulumi + .all([ + stack.construct.workersCustomDomain.id, + stack.construct.workersCustomDomain.urn, + stack.construct.workersCustomDomain.accountId, + stack.construct.workersCustomDomain.hostname, + stack.construct.workersCustomDomain.service, + stack.construct.workersCustomDomain.zoneId, + ]) + .apply(([id, urn, accountId, hostname, service, zoneId]) => { + expect(id).toEqual('test-worker-domain-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/workersCustomDomain:WorkersCustomDomain::test-worker-domain-dev' + ) + expect(accountId).toEqual('test-account') + expect(hostname).toEqual('test.gradientedge.io') + expect(service).toEqual('product-service') + expect(zoneId).toEqual('test-worker-domain-dev-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/services/worker-manager.test.ts1 b/src/test/cloudflare/services/worker-manager.test.ts1 deleted file mode 100644 index 748c6cd1..00000000 --- a/src/test/cloudflare/services/worker-manager.test.ts1 +++ /dev/null @@ -1,297 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import fs from 'fs' -import { - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - WorkerCronTriggerProps, - WorkerDomainProps, - WorkerRouteProps, - WorkerScriptProps, - WorkersKvNamespaceProps, - WorkersKvProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testWorkerDomain: WorkerDomainProps - testWorkerRoute: WorkerRouteProps - testWorkerScript: WorkerScriptProps - testWorkersKvNamespace: WorkersKvNamespaceProps - testWorkersKv: WorkersKvProps - testWorkerCronTrigger: WorkerCronTriggerProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/worker.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testWorkerCronTrigger: this.node.tryGetContext('testWorkerCronTrigger'), - testWorkerDomain: this.node.tryGetContext('testWorkerDomain'), - testWorkerRoute: this.node.tryGetContext('testWorkerRoute'), - testWorkerScript: this.node.tryGetContext('testWorkerScript'), - testWorkersKv: this.node.tryGetContext('testWorkersKv'), - testWorkersKvNamespace: this.node.tryGetContext('testWorkersKvNamespace'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testWorkerCronTrigger: this.node.tryGetContext('testWorkerCronTrigger'), - testWorkerRoute: this.node.tryGetContext('testWorkerRoute'), - testWorkerScript: this.node.tryGetContext('testWorkerScript'), - testWorkersKv: this.node.tryGetContext('testWorkersKv'), - testWorkersKvNamespace: this.node.tryGetContext('testWorkersKvNamespace'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - const zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { - zoneId: zone.id, - }) - this.workerManager.createWorkerDomain(`test-worker-domain-${this.props.stage}`, this, this.props.testWorkerDomain) - this.workerManager.createWorkerRoute(`test-worker-route-${this.props.stage}`, this, this.props.testWorkerRoute) - const testScript = this.workerManager.createWorkerScript(`test-worker-script-${this.props.stage}`, this, { - ...this.props.testWorkerScript, - content: fs.readFileSync('src/test/cloudflare/common/sample.js', { encoding: 'utf8' }), - }) - const workerKvNsId = this.workerManager.createWorkersKvNamespace( - `test-workers-kv-ns-${this.props.stage}`, - this, - this.props.testWorkersKvNamespace - ) - this.workerManager.createWorkersKv(`test-workers-kv-${this.props.stage}`, this, { - ...this.props.testWorkersKv, - namespaceId: workerKvNsId.id, - }) - this.workerManager.createWorkerCronTrigger( - `test-worker-trigger-${this.props.stage}`, - this, - this.props.testWorkerCronTrigger - ) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareWorkerManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-worker-domain-dev') - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testWorkerDomainDevWorkerDomainFriendlyUniqueId: { value: 'test-worker-domain-dev' }, - testWorkerDomainDevWorkerDomainId: { value: '${cloudflare_workers_custom_domain.test-worker-domain-dev.id}' }, - testWorkerRouteDevWorkerRouteFriendlyUniqueId: { value: 'test-worker-route-dev' }, - testWorkerRouteDevWorkerRouteId: { value: '${cloudflare_workers_route.test-worker-route-dev.id}' }, - testWorkerScriptDevWorkerScriptFriendlyUniqueId: { value: 'test-worker-script-dev' }, - testWorkerScriptDevWorkerScriptId: { value: '${cloudflare_workers_script.test-worker-script-dev.id}' }, - testWorkerTriggerDevWorkerCronTriggerFriendlyUniqueId: { value: 'test-worker-trigger-dev' }, - testWorkerTriggerDevWorkerCronTriggerId: { - value: '${cloudflare_workers_cron_trigger.test-worker-trigger-dev.id}', - }, - testWorkersKvDevWorkersKvFriendlyUniqueId: { value: 'test-workers-kv-dev' }, - testWorkersKvDevWorkersKvId: { value: '${cloudflare_workers_kv.test-workers-kv-dev.id}' }, - testWorkersKvNsDevWorkersKvNamespaceFriendlyUniqueId: { value: 'test-workers-kv-ns-dev' }, - testWorkersKvNsDevWorkersKvNamespaceId: { - value: '${cloudflare_workers_kv_namespace.test-workers-kv-ns-dev.id}', - }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - }) - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions worker domain as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersCustomDomain', { - account_id: 'test-account', - hostname: 'test.gradientedge.io', - service: 'product-service', - zone_id: '${data.cloudflare_zone.test-worker-domain-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions worker domain as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersRoute', { - pattern: 'gradientedge.io/*', - zone_id: '${data.cloudflare_zone.test-worker-route-dev-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions worker script as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersScript', { - account_id: 'test-account', - bindings: [ - { - dataset: 'sample_dataset', - name: 'sample_dataset_binding', - type: 'analytics_engine', - }, - { - name: 'sample_kv_namespace_binding', - type: 'kv_namespace', - }, - { - name: 'sample_text_binding', - text: 'example', - type: 'plain_text', - }, - { - name: 'sample_bucket_binding', - type: 'r2_bucket', - }, - { - name: 'sample_secret_text_binding', - text: 'example', - type: 'secret_text', - }, - { - environment: 'development', - name: 'sample_service_binding', - service: 'sample_service', - type: 'service', - }, - ], - content: - 'exports.handler = async function (event, context, callback) {\n console.debug(`Event: ${JSON.stringify(event)}`)\n console.debug(`Context: ${JSON.stringify(context)}`)\n return callback(null, { statusCode: 200 })\n}\n', - script_name: 'test-script-dev', - }) - ) - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions workers kv namespace as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersKvNamespace', { - account_id: 'test-account', - title: 'test-namespace-dev', - }) - ) - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions workers kv as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersKv', { - account_id: 'test-account', - key_name: 'test', - namespace_id: '${cloudflare_workers_kv_namespace.test-workers-kv-ns-dev.id}', - value: 'test123', - }) - ) - }) -}) - -describe('TestCloudflareWorkerManager', () => { - test('provisions worker cron trigger as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersCronTrigger', { - account_id: 'test-account', - schedules: [ - { - cron: '*/5 * * * *', - }, - { - cron: '10 7 * * mon-fri', - }, - ], - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/zone-manager.test.ts b/src/test/cloudflare/services/zone-manager.test.ts new file mode 100644 index 00000000..7ed99151 --- /dev/null +++ b/src/test/cloudflare/services/zone-manager.test.ts @@ -0,0 +1,196 @@ +import { + Zone, + ZoneCacheReserve, + ZoneCacheVariants, + ZoneDnssec, + ZoneHold, + ZoneLockdown, + ZoneSetting, +} from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import { + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + ZoneCacheVariantsProps, + ZoneLockdownProps, + ZoneProps, + ZoneSettingProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testZoneCacheVariants: ZoneCacheVariantsProps + testZoneLockdown: ZoneLockdownProps + testZoneSetting: ZoneSettingProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: ['src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/zone.json'], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/aws/common/cdkEnv', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: CommonCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + testZone: undefined, + } + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + zoneCacheVariants: ZoneCacheVariants + zoneDnssec: ZoneDnssec + zoneHold: ZoneHold + zoneLockdown: ZoneLockdown + zoneSetting: ZoneSetting + zoneCacheReserve: ZoneCacheReserve + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.zoneCacheReserve = this.zoneManager.createZoneCacheReserve( + `test-zone-cache-reserve-${this.props.stage}`, + this, + { + zoneId: this.zone.id, + } + ) + this.zoneCacheVariants = this.zoneManager.createZoneCacheVariants( + `test-zone-cache-variants-${this.props.stage}`, + this, + { + ...this.props.testZoneCacheVariants, + } + ) + this.zoneDnssec = this.zoneManager.createZoneDnssec(`test-zone-dnssec-${this.props.stage}`, this, { + zoneId: this.zone.id, + }) + this.zoneHold = this.zoneManager.createZoneHold(`test-zone-hold-${this.props.stage}`, this, { + zoneId: this.zone.id, + }) + this.zoneLockdown = this.zoneManager.createZoneLockdown( + `test-zone-lockdown-${this.props.stage}`, + this, + this.props.testZoneLockdown + ) + this.zoneSetting = this.zoneManager.createZoneSetting( + `test-zone-settings-${this.props.stage}`, + this, + this.props.testZoneSetting + ) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareZoneManager', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareZoneManager', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareZoneManager', () => { + expect(stack.construct.zoneCacheReserve).toBeDefined() + test('provisions zone cache reserve as expected', () => { + pulumi + .all([ + stack.construct.zoneCacheReserve.id, + stack.construct.zoneCacheReserve.urn, + stack.construct.zoneCacheReserve.zoneId, + ]) + .apply(([id, urn, zoneId]) => { + expect(id).toEqual('test-zone-cache-reserve-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zoneCacheReserve:ZoneCacheReserve::test-zone-cache-reserve-dev' + ) + expect(zoneId).toEqual('test-zone-dev-id') + }) + }) +}) + +describe('TestCloudflareZoneManager', () => { + expect(stack.construct.zoneCacheVariants).toBeDefined() + test('provisions zone cache variants as expected', () => { + pulumi + .all([ + stack.construct.zoneCacheVariants.id, + stack.construct.zoneCacheVariants.urn, + stack.construct.zoneCacheVariants.value, + stack.construct.zoneCacheVariants.zoneId, + ]) + .apply(([id, urn, value, zoneId]) => { + expect(id).toEqual('test-zone-cache-variants-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zoneCacheVariants:ZoneCacheVariants::test-zone-cache-variants-dev' + ) + expect(value).toEqual({ + avif: ['image/avif', 'image/webp'], + bmp: ['image/bmp', 'image/webp'], + gif: ['image/gif', 'image/webp'], + jp2: ['image/jp2', 'image/webp'], + jpeg: ['image/jpeg', 'image/webp'], + jpg: ['image/jpg', 'image/webp'], + jpg2: ['image/jpg2', 'image/webp'], + png: ['image/png', 'image/webp'], + tif: ['image/tif', 'image/webp'], + tiff: ['image/tiff', 'image/webp'], + webp: ['image/jpeg', 'image/webp'], + }) + expect(zoneId).toEqual('test-zone-cache-variants-dev-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/services/zone-manager.test.ts1 b/src/test/cloudflare/services/zone-manager.test.ts1 deleted file mode 100644 index f438126a..00000000 --- a/src/test/cloudflare/services/zone-manager.test.ts1 +++ /dev/null @@ -1,239 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - ZoneCacheVariantsProps, - ZoneLockdownProps, - ZoneProps, - ZoneSettingProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testZoneCacheVariants: ZoneCacheVariantsProps - testZoneLockdown: ZoneLockdownProps - testZoneSetting: ZoneSettingProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: ['src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/zone.json'], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - testZoneCacheVariants: this.node.tryGetContext('testZoneCacheVariants'), - testZoneLockdown: this.node.tryGetContext('testZoneLockdown'), - testZoneSetting: this.node.tryGetContext('testZoneSetting'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testZoneCacheVariants: this.node.tryGetContext('testZoneCacheVariants'), - testZoneLockdown: this.node.tryGetContext('testZoneLockdown'), - testZoneSetting: this.node.tryGetContext('testZoneSetting'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - const zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { - zoneId: zone.id, - }) - this.zoneManager.createZoneCacheVariants(`test-zone-cache-variants-${this.props.stage}`, this, { - ...this.props.testZoneCacheVariants, - }) - this.zoneManager.createZoneDnssec(`test-zone-dnssec-${this.props.stage}`, this, { - zoneId: zone.id, - }) - this.zoneManager.createZoneHold(`test-zone-hold-${this.props.stage}`, this, { - zoneId: zone.id, - }) - this.zoneManager.createZoneLockdown(`test-zone-lockdown-${this.props.stage}`, this, this.props.testZoneLockdown) - this.zoneManager.createZoneSetting(`test-zone-settings-${this.props.stage}`, this, this.props.testZoneSetting) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareZoneManager', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-zone-dev') - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testZoneCacheReserveDevZoneCacheReserveFriendlyUniqueId: { value: 'test-zone-cache-reserve-dev' }, - testZoneCacheReserveDevZoneCacheReserveId: { - value: '${cloudflare_zone_cache_reserve.test-zone-cache-reserve-dev.id}', - }, - testZoneCacheVariantsDevZoneCacheVariantsFriendlyUniqueId: { value: 'test-zone-cache-variants-dev' }, - testZoneCacheVariantsDevZoneCacheVariantsId: { - value: '${cloudflare_zone_cache_variants.test-zone-cache-variants-dev.id}', - }, - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - testZoneDnssecDevZoneDnssecFriendlyUniqueId: { value: 'test-zone-dnssec-dev' }, - testZoneDnssecDevZoneDnssecId: { value: '${cloudflare_zone_dnssec.test-zone-dnssec-dev.id}' }, - testZoneHoldDevZoneHoldFriendlyUniqueId: { value: 'test-zone-hold-dev' }, - testZoneHoldDevZoneHoldId: { value: '${cloudflare_zone_hold.test-zone-hold-dev.id}' }, - testZoneLockdownDevZoneLockdownFriendlyUniqueId: { value: 'test-zone-lockdown-dev' }, - testZoneLockdownDevZoneLockdownId: { value: '${cloudflare_zone_lockdown.test-zone-lockdown-dev.id}' }, - }) - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions zone cache reserve as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZoneCacheReserve', { - zone_id: '${cloudflare_zone.test-zone-dev.id}', - }) - ) - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions zone cache variants as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZoneCacheVariants', { - value: { - avif: ['image/avif', 'image/webp'], - bmp: ['image/bmp', 'image/webp'], - gif: ['image/gif', 'image/webp'], - jp2: ['image/jp2', 'image/webp'], - jpeg: ['image/jpeg', 'image/webp'], - jpg: ['image/jpg', 'image/webp'], - jpg2: ['image/jpg2', 'image/webp'], - png: ['image/png', 'image/webp'], - tif: ['image/tif', 'image/webp'], - tiff: ['image/tiff', 'image/webp'], - webp: ['image/jpeg', 'image/webp'], - }, - zone_id: '${data.cloudflare_zone.test-zone-cache-variants-dev-data-zone-data-zone.id}', - }) - ) - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions zone dnssec as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZoneDnssec', { - zone_id: '${cloudflare_zone.test-zone-dev.id}', - }) - ) - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions zone hold as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZoneHold', { - zone_id: '${cloudflare_zone.test-zone-dev.id}', - }) - ) - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions zone lockdown as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZoneLockdown', { - configurations: { - target: 'ip_range', - value: '192.0.2.0/24', - }, - urls: ['gradientedge.io/api/product*'], - zone_id: '${data.cloudflare_zone.test-zone-lockdown-dev-data-zone-data-zone.id}', - }) - ) - }) -}) - -describe('TestCloudflareZoneManager', () => { - test('provisions zone settings override as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZoneSetting', { - setting_id: 'always_online', - value: 'on', - zone_id: '${data.cloudflare_zone.test-zone-settings-dev-data-zone-data-zone.id}', - }) - ) - }) -}) diff --git a/tsconfig.json b/tsconfig.json index 36516fe0..2b1ca2a8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,14 +28,14 @@ "index.ts", "src/**/*.ts", "app/**/*.ts", - "src/test/cloudflare/services/zone-manager.test.ts1", - "src/test/cloudflare/services/worker-manager.test.ts1", - "src/test/cloudflare/services/rule-set-manager.test.ts1", - "src/test/cloudflare/services/record-manager.test.ts1", - "src/test/cloudflare/services/page-manager.test.ts1", - "src/test/cloudflare/services/firewall-manager.test.ts1", - "src/test/cloudflare/services/argo-manager.test.ts1", - "src/test/cloudflare/services/api-shield-manager.test.ts1", + "src/test/cloudflare/services/zone-manager.test.ts", + "src/test/cloudflare/services/worker-manager.test.ts", + "src/test/cloudflare/services/rule-set-manager.test.ts", + "src/test/cloudflare/services/record-manager.test.ts", + "src/test/cloudflare/services/page-manager.test.ts", + "src/test/cloudflare/services/firewall-manager.test.ts", + "src/test/cloudflare/services/argo-manager.test.ts", + "src/test/cloudflare/services/api-shield-manager.test.ts", "src/test/cloudflare/services/access-manager.pulumi.test.ts1", "src/test/cloudflare/construct/worker-site.test.ts1", "src/test/cloudflare/construct/pages-static-site.test.ts1", From 3415f8589a8c8d440b935ecb53560cb6997ef117 Mon Sep 17 00:00:00 2001 From: Srinidhi Veeraraghavan Date: Thu, 15 Jan 2026 19:04:57 +0000 Subject: [PATCH 7/7] feat: adding tests for cloudflare constructs --- .../construct/pages-static-site/main.ts | 12 +- .../cloudflare/construct/worker-site/main.ts | 37 ++-- .../cloudflare/common/cdkConfig/record.json | 14 -- .../common-cloudflare-construct.test.ts | 99 +++++++++ .../common-cloudflare-construct.test.ts1 | 99 --------- .../common/{cdkConfig => config}/access.json | 0 .../{cdkConfig => config}/api-shield.json | 0 .../common/{cdkConfig => config}/argo.json | 0 .../common/{cdkConfig => config}/dummy.json | 0 .../common/{cdkConfig => config}/filter.json | 0 .../{cdkConfig => config}/firewall.json | 0 .../common/{cdkConfig => config}/pages.json | 4 + src/test/cloudflare/common/config/record.json | 20 ++ .../{cdkConfig => config}/rule-set.json | 8 + .../common/{cdkConfig => config}/worker.json | 41 ++++ .../common/{cdkConfig => config}/zone.json | 12 +- .../common/{cdkEnv => env}/dev.json | 0 .../construct/pages-static-site.test.ts | 181 ++++++++++++++++ .../construct/pages-static-site.test.ts1 | 179 ---------------- .../cloudflare/construct/worker-site.test.ts | 202 ++++++++++++++++++ .../cloudflare/construct/worker-site.test.ts1 | 182 ---------------- .../services/access-manager.test.ts | 8 +- .../services/api-shield-manager.test.ts | 8 +- .../cloudflare/services/argo-manager.test.ts | 8 +- .../services/firewall-manager.test.ts | 10 +- .../cloudflare/services/page-manager.test.ts | 4 +- .../services/record-manager.test.ts | 8 +- .../services/rule-set-manager.test.ts | 8 +- .../services/worker-manager.test.ts | 8 +- .../cloudflare/services/zone-manager.test.ts | 4 +- tsconfig.json | 6 +- 31 files changed, 629 insertions(+), 533 deletions(-) delete mode 100644 src/test/cloudflare/common/cdkConfig/record.json create mode 100644 src/test/cloudflare/common/common-cloudflare-construct.test.ts delete mode 100644 src/test/cloudflare/common/common-cloudflare-construct.test.ts1 rename src/test/cloudflare/common/{cdkConfig => config}/access.json (100%) rename src/test/cloudflare/common/{cdkConfig => config}/api-shield.json (100%) rename src/test/cloudflare/common/{cdkConfig => config}/argo.json (100%) rename src/test/cloudflare/common/{cdkConfig => config}/dummy.json (100%) rename src/test/cloudflare/common/{cdkConfig => config}/filter.json (100%) rename src/test/cloudflare/common/{cdkConfig => config}/firewall.json (100%) rename src/test/cloudflare/common/{cdkConfig => config}/pages.json (93%) create mode 100644 src/test/cloudflare/common/config/record.json rename src/test/cloudflare/common/{cdkConfig => config}/rule-set.json (50%) rename src/test/cloudflare/common/{cdkConfig => config}/worker.json (61%) rename src/test/cloudflare/common/{cdkConfig => config}/zone.json (83%) rename src/test/cloudflare/common/{cdkEnv => env}/dev.json (100%) create mode 100644 src/test/cloudflare/construct/pages-static-site.test.ts delete mode 100644 src/test/cloudflare/construct/pages-static-site.test.ts1 create mode 100644 src/test/cloudflare/construct/worker-site.test.ts delete mode 100644 src/test/cloudflare/construct/worker-site.test.ts1 diff --git a/src/lib/cloudflare/construct/pages-static-site/main.ts b/src/lib/cloudflare/construct/pages-static-site/main.ts index 82a4a2e0..a23d4058 100644 --- a/src/lib/cloudflare/construct/pages-static-site/main.ts +++ b/src/lib/cloudflare/construct/pages-static-site/main.ts @@ -110,12 +110,12 @@ export class CloudflarePagesStaticSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected async resolveSecretFromAWS(secretName: string, secretKey: string) { + protected resolveSecretFromAWS(secretName: string, secretKey: string) { if (this.config.require('secretsProvider') !== 'aws') return - const secret = await aws.secretsmanager.getSecret({ name: secretName }) - const secretVersion = await aws.secretsmanager.getSecretVersion({ secretId: secret.id }) + const secret = aws.secretsmanager.getSecretOutput({ name: secretName }) + const secretVersion = aws.secretsmanager.getSecretVersionOutput({ secretId: secret.id }) if (!secretVersion) throw new Error(`Unable to resolve secret:${secretName}`) - return await std.jsondecode({ input: secretVersion.secretString }) + return std.jsondecodeOutput({ input: secretVersion.secretString }) } /** @@ -126,9 +126,9 @@ export class CloudflarePagesStaticSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected async resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string) { + protected resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string) { if (this.config.require('secretsProvider') !== 'azure') return - const secretValueData = await azure.keyvault.getSecret({ + const secretValueData = azure.keyvault.getSecretOutput({ resourceGroupName, secretName: secretKey, vaultName: keyVaultName, diff --git a/src/lib/cloudflare/construct/worker-site/main.ts b/src/lib/cloudflare/construct/worker-site/main.ts index 1e3ce4ec..001862fe 100644 --- a/src/lib/cloudflare/construct/worker-site/main.ts +++ b/src/lib/cloudflare/construct/worker-site/main.ts @@ -1,9 +1,10 @@ import * as aws from '@pulumi/aws' import * as azure from '@pulumi/azure-native' -import { WorkersScript, Zone } from '@pulumi/cloudflare' +import { Ruleset, WorkersCustomDomain, WorkersScript, Zone, ZoneSetting } from '@pulumi/cloudflare' import { WorkersScriptBinding } from '@pulumi/cloudflare/types/input.js' import { ComponentResourceOptions } from '@pulumi/pulumi' import * as std from '@pulumi/std' +import fs from 'fs' import { CommonCloudflareConstruct } from '../../common/index.js' import { CloudflareWorkerSiteProps } from './types.js' @@ -28,6 +29,9 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { /* worker site resources */ siteZone: Zone siteWorkerScript: WorkersScript + siteWorkerDomain: WorkersCustomDomain + siteRuleSet: Ruleset + siteZoneSetting: ZoneSetting workerPlainTextBindingEnvironmentVariables: WorkersScriptBinding[] = [] workerSecretTextBindingEnvironmentVariables: WorkersScriptBinding[] = [] @@ -76,14 +80,11 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { /** * @summary Create the worker */ - protected async createWorker() { - const workerContent = std.file({ - input: this.props.siteWorkerAsset, - }) - + protected createWorker() { + const workerContent = fs.readFileSync(this.props.siteWorkerAsset, 'utf-8') this.siteWorkerScript = this.workerManager.createWorkerScript(`${this.id}-worker-script`, this, { ...this.props.siteWorkerScript, - content: (await workerContent).result, + content: workerContent, }) } @@ -91,7 +92,7 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { * @summary Create the worker domain */ protected createWorkerDomain() { - this.workerManager.createWorkerDomain(`${this.id}-worker-domain`, this, { + this.siteWorkerDomain = this.workerManager.createWorkerDomain(`${this.id}-worker-domain`, this, { ...this.props.siteWorkerDomain, environment: this.props.siteWorkerDomain.environment ?? 'production', hostname: `${this.props.siteSubDomain}.${this.props.domainName}`, @@ -105,12 +106,12 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected async resolveSecretFromAWS(secretName: string, secretKey: string) { + protected resolveSecretFromAWS(secretName: string, secretKey: string) { if (this.config.require('secretsProvider') !== 'aws') return - const secret = await aws.secretsmanager.getSecret({ name: secretName }) - const secretVersion = await aws.secretsmanager.getSecretVersion({ secretId: secret.id }) + const secret = aws.secretsmanager.getSecretOutput({ name: secretName }) + const secretVersion = aws.secretsmanager.getSecretVersionOutput({ secretId: secret.id }) if (!secretVersion) throw new Error(`Unable to resolve secret:${secretName}`) - return await std.jsondecode({ input: secretVersion.secretString }) + return std.jsondecodeOutput({ input: secretVersion.secretString }) } /** @@ -121,9 +122,9 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { * @param secretKey the secret key * @returns the secret value */ - protected async resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string) { + protected resolveSecretFromAzure(resourceGroupName: string, keyVaultName: string, secretKey: string) { if (this.config.require('secretsProvider') !== 'azure') return - const secretValueData = await azure.keyvault.getSecret({ + const secretValueData = azure.keyvault.getSecretOutput({ resourceGroupName, secretName: secretKey, vaultName: keyVaultName, @@ -137,7 +138,7 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { */ protected createRuleset() { if (!this.props.siteRuleSet) return - this.ruleSetManager.createRuleSet(`${this.id}-rule`, this, this.props.siteRuleSet) + this.siteRuleSet = this.ruleSetManager.createRuleSet(`${this.id}-rule`, this, this.props.siteRuleSet) } /** @@ -145,6 +146,10 @@ export class CloudflareWorkerSite extends CommonCloudflareConstruct { */ protected createZoneSetting() { if (!this.props.siteZoneSetting) return - this.zoneManager.createZoneSetting(`${this.id}-zone-setting`, this, this.props.siteZoneSetting) + this.siteZoneSetting = this.zoneManager.createZoneSetting( + `${this.id}-zone-setting`, + this, + this.props.siteZoneSetting + ) } } diff --git a/src/test/cloudflare/common/cdkConfig/record.json b/src/test/cloudflare/common/cdkConfig/record.json deleted file mode 100644 index 88667db2..00000000 --- a/src/test/cloudflare/common/cdkConfig/record.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "testARecord": { - "name": "testARecord", - "ttl": 300, - "type": "A", - "content": "192.0.2.1" - }, - "testCNameRecord": { - "name": "testCNameRecord", - "ttl": 300, - "type": "CNAME", - "content": "example.gradientedge.io" - } -} diff --git a/src/test/cloudflare/common/common-cloudflare-construct.test.ts b/src/test/cloudflare/common/common-cloudflare-construct.test.ts new file mode 100644 index 00000000..cbabfb9b --- /dev/null +++ b/src/test/cloudflare/common/common-cloudflare-construct.test.ts @@ -0,0 +1,99 @@ +import { Zone, ZoneCacheReserve } from '@pulumi/cloudflare' +import * as pulumi from '@pulumi/pulumi' +import { + CommonCloudflareConstruct, + CommonCloudflareStack, + CommonCloudflareStackProps, + ZoneProps, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CommonCloudflareStackProps { + testZone: ZoneProps + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: ['src/test/cloudflare/common/config/dummy.json', 'src/test/cloudflare/common/config/zone.json'], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/cloudflare/common/env', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } +} + +class TestCommonConstruct extends CommonCloudflareConstruct { + declare props: TestCloudflareStackProps + zone: Zone + zoneCacheReserve: ZoneCacheReserve + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) + this.zoneCacheReserve = this.zoneManager.createZoneCacheReserve( + `test-zone-cache-reserve-${this.props.stage}`, + this, + { + zoneId: this.zone.id, + } + ) + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareCommonConstruct', () => { + expect(stack.construct.zone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([stack.construct.zone.id, stack.construct.zone.urn, stack.construct.zone.name, stack.construct.zone.account]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-zone-dev-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-zone-dev') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareCommonConstruct', () => { + expect(stack.construct.zoneCacheReserve).toBeDefined() + test('provisions zone cache reserve as expected', () => { + pulumi + .all([ + stack.construct.zoneCacheReserve.id, + stack.construct.zoneCacheReserve.urn, + stack.construct.zoneCacheReserve.zoneId, + ]) + .apply(([id, urn, zoneId]) => { + expect(id).toEqual('test-zone-cache-reserve-dev-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zoneCacheReserve:ZoneCacheReserve::test-zone-cache-reserve-dev' + ) + expect(zoneId).toEqual('test-zone-dev-id') + }) + }) +}) diff --git a/src/test/cloudflare/common/common-cloudflare-construct.test.ts1 b/src/test/cloudflare/common/common-cloudflare-construct.test.ts1 deleted file mode 100644 index 2615c7a2..00000000 --- a/src/test/cloudflare/common/common-cloudflare-construct.test.ts1 +++ /dev/null @@ -1,99 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CommonCloudflareConstruct, - CommonCloudflareStack, - CommonCloudflareStackProps, - ZoneProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CommonCloudflareStackProps { - testZone: ZoneProps - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: ['src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/zone.json'], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - testZone: this.node.tryGetContext('testZone'), - } - } -} - -class TestCommonConstruct extends CommonCloudflareConstruct { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - const zone = this.zoneManager.createZone(`test-zone-${this.props.stage}`, this, this.props.testZone) - this.zoneManager.createZoneCacheReserve(`test-zone-cache-reserve-${this.props.stage}`, this, { - zoneId: zone.id, - }) - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareCommonConstruct', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareCommonConstruct', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareCommonConstruct', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testZoneDevZoneFriendlyUniqueId: { value: 'test-zone-dev' }, - testZoneDevZoneId: { value: '${cloudflare_zone.test-zone-dev.id}' }, - testZoneDevZoneName: { value: '${cloudflare_zone.test-zone-dev.name}' }, - }) - }) -}) - -describe('TestCloudflareCommonConstruct', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) diff --git a/src/test/cloudflare/common/cdkConfig/access.json b/src/test/cloudflare/common/config/access.json similarity index 100% rename from src/test/cloudflare/common/cdkConfig/access.json rename to src/test/cloudflare/common/config/access.json diff --git a/src/test/cloudflare/common/cdkConfig/api-shield.json b/src/test/cloudflare/common/config/api-shield.json similarity index 100% rename from src/test/cloudflare/common/cdkConfig/api-shield.json rename to src/test/cloudflare/common/config/api-shield.json diff --git a/src/test/cloudflare/common/cdkConfig/argo.json b/src/test/cloudflare/common/config/argo.json similarity index 100% rename from src/test/cloudflare/common/cdkConfig/argo.json rename to src/test/cloudflare/common/config/argo.json diff --git a/src/test/cloudflare/common/cdkConfig/dummy.json b/src/test/cloudflare/common/config/dummy.json similarity index 100% rename from src/test/cloudflare/common/cdkConfig/dummy.json rename to src/test/cloudflare/common/config/dummy.json diff --git a/src/test/cloudflare/common/cdkConfig/filter.json b/src/test/cloudflare/common/config/filter.json similarity index 100% rename from src/test/cloudflare/common/cdkConfig/filter.json rename to src/test/cloudflare/common/config/filter.json diff --git a/src/test/cloudflare/common/cdkConfig/firewall.json b/src/test/cloudflare/common/config/firewall.json similarity index 100% rename from src/test/cloudflare/common/cdkConfig/firewall.json rename to src/test/cloudflare/common/config/firewall.json diff --git a/src/test/cloudflare/common/cdkConfig/pages.json b/src/test/cloudflare/common/config/pages.json similarity index 93% rename from src/test/cloudflare/common/cdkConfig/pages.json rename to src/test/cloudflare/common/config/pages.json index 2bd10603..6bf5b2e3 100644 --- a/src/test/cloudflare/common/cdkConfig/pages.json +++ b/src/test/cloudflare/common/config/pages.json @@ -1,4 +1,8 @@ { + "sitePagesProject": { + "name": "test-simple-project", + "productionBranch": "main" + }, "testPageRule": { "actions": { "emailObfuscation": "on", diff --git a/src/test/cloudflare/common/config/record.json b/src/test/cloudflare/common/config/record.json new file mode 100644 index 00000000..415e2fb9 --- /dev/null +++ b/src/test/cloudflare/common/config/record.json @@ -0,0 +1,20 @@ +{ + "siteCnameRecord": { + "content": "example.gradientedge.io", + "name": "testCNameRecord", + "ttl": 300, + "type": "CNAME" + }, + "testARecord": { + "content": "192.0.2.1", + "name": "testARecord", + "ttl": 300, + "type": "A" + }, + "testCNameRecord": { + "content": "example.gradientedge.io", + "name": "testCNameRecord", + "ttl": 300, + "type": "CNAME" + } +} diff --git a/src/test/cloudflare/common/cdkConfig/rule-set.json b/src/test/cloudflare/common/config/rule-set.json similarity index 50% rename from src/test/cloudflare/common/cdkConfig/rule-set.json rename to src/test/cloudflare/common/config/rule-set.json index d5ed70b7..a4761108 100644 --- a/src/test/cloudflare/common/cdkConfig/rule-set.json +++ b/src/test/cloudflare/common/config/rule-set.json @@ -1,4 +1,12 @@ { + "siteRuleSet": { + "kind": "custom", + "name": "testRuleSet", + "phase": "http*ratelimit", + "rules": { + "action": "set_cache_settings" + } + }, "testRuleSet": { "kind": "custom", "name": "testRuleSet", diff --git a/src/test/cloudflare/common/cdkConfig/worker.json b/src/test/cloudflare/common/config/worker.json similarity index 61% rename from src/test/cloudflare/common/cdkConfig/worker.json rename to src/test/cloudflare/common/config/worker.json index fa1fa8c5..9b53392e 100644 --- a/src/test/cloudflare/common/cdkConfig/worker.json +++ b/src/test/cloudflare/common/config/worker.json @@ -1,4 +1,45 @@ { + "siteWorkerDomain": { + "accountId": "test-account", + "environment": "development", + "hostname": "test.gradientedge.io", + "service": "product-service" + }, + "siteWorkerScript": { + "accountId": "test-account", + "bindings": [ + { + "dataset": "sample_dataset", + "name": "sample_dataset_binding", + "type": "analytics_engine" + }, + { + "name": "sample_kv_namespace_binding", + "type": "kv_namespace" + }, + { + "name": "sample_text_binding", + "text": "example", + "type": "plain_text" + }, + { + "name": "sample_bucket_binding", + "type": "r2_bucket" + }, + { + "name": "sample_secret_text_binding", + "text": "example", + "type": "secret_text" + }, + { + "environment": "development", + "name": "sample_service_binding", + "service": "sample_service", + "type": "service" + } + ], + "scriptName": "test-script" + }, "testWorkerCronTrigger": { "accountId": "test-account", "schedules": [ diff --git a/src/test/cloudflare/common/cdkConfig/zone.json b/src/test/cloudflare/common/config/zone.json similarity index 83% rename from src/test/cloudflare/common/cdkConfig/zone.json rename to src/test/cloudflare/common/config/zone.json index b1d18d8c..343035b8 100644 --- a/src/test/cloudflare/common/cdkConfig/zone.json +++ b/src/test/cloudflare/common/config/zone.json @@ -1,4 +1,14 @@ { + "siteZone": { + "account": { + "id": "test-account" + } + }, + "siteZoneSetting": { + "id": "0rtt", + "settingId": "always_online", + "value": "on" + }, "testZone": { "account": { "id": "test-account" @@ -28,8 +38,8 @@ "urls": ["gradientedge.io/api/product*"] }, "testZoneSetting": { - "settingId": "always_online", "id": "0rtt", + "settingId": "always_online", "value": "on" } } diff --git a/src/test/cloudflare/common/cdkEnv/dev.json b/src/test/cloudflare/common/env/dev.json similarity index 100% rename from src/test/cloudflare/common/cdkEnv/dev.json rename to src/test/cloudflare/common/env/dev.json diff --git a/src/test/cloudflare/construct/pages-static-site.test.ts b/src/test/cloudflare/construct/pages-static-site.test.ts new file mode 100644 index 00000000..e471fc07 --- /dev/null +++ b/src/test/cloudflare/construct/pages-static-site.test.ts @@ -0,0 +1,181 @@ +import * as pulumi from '@pulumi/pulumi' +import { + CloudflarePagesStaticSite, + CloudflarePagesStaticSiteProps, + CommonCloudflareStack, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CloudflarePagesStaticSiteProps { + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/pages.json', + 'src/test/cloudflare/common/config/record.json', + 'src/test/cloudflare/common/config/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/cloudflare/common/env', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: TestCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + siteAssetDir: `src/test/cloudflare/common/sample.html`, + siteSubDomain: `test.app`, + } + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: TestCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + sitePagesProject: undefined, + } + } +} + +class TestCommonConstruct extends CloudflarePagesStaticSite { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.initResources() + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflarePagesStaticSite', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflarePagesStaticSite', () => { + expect(stack.construct.siteZone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([ + stack.construct.siteZone.id, + stack.construct.siteZone.urn, + stack.construct.siteZone.name, + stack.construct.siteZone.account, + ]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-common-stack-zone-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-common-stack-zone') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflarePagesStaticSite', () => { + expect(stack.construct.sitePagesProject).toBeDefined() + test('provisions pages project as expected', () => { + pulumi + .all([ + stack.construct.sitePagesProject.id, + stack.construct.sitePagesProject.urn, + stack.construct.sitePagesProject.accountId, + stack.construct.sitePagesProject.name, + stack.construct.sitePagesProject.productionBranch, + ]) + .apply(([id, urn, accountId, name, productionBranch]) => { + expect(id).toEqual('test-common-stack-site-project-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/pagesProject:PagesProject::test-common-stack-site-project' + ) + expect(accountId).toEqual('123456789012') + expect(name).toEqual('test-simple-project-dev') + expect(productionBranch).toEqual('main') + }) + }) +}) + +describe('TestCloudflarePagesStaticSite', () => { + expect(stack.construct.sitePagesDomain).toBeDefined() + test('provisions pages domain as expected', () => { + pulumi + .all([ + stack.construct.sitePagesDomain.id, + stack.construct.sitePagesDomain.urn, + stack.construct.sitePagesDomain.accountId, + stack.construct.sitePagesDomain.name, + stack.construct.sitePagesDomain.projectName, + ]) + .apply(([id, urn, accountId, name, projectName]) => { + expect(id).toEqual('test-common-stack-site-domain-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/pagesDomain:PagesDomain::test-common-stack-site-domain' + ) + expect(accountId).toEqual('123456789012') + expect(name).toEqual('test.app.gradientedge.io') + expect(projectName).toEqual('test-simple-project-dev') + }) + }) +}) + +describe('TestCloudflarePagesStaticSite', () => { + expect(stack.construct.sitePagesCnameRecord).toBeDefined() + test('provisions CNAME record as expected', () => { + pulumi + .all([ + stack.construct.sitePagesCnameRecord.id, + stack.construct.sitePagesCnameRecord.urn, + stack.construct.sitePagesCnameRecord.name, + stack.construct.sitePagesCnameRecord.ttl, + stack.construct.sitePagesCnameRecord.type, + stack.construct.sitePagesCnameRecord.content, + stack.construct.sitePagesCnameRecord.zoneId, + ]) + .apply(([id, urn, name, ttl, type, content, zoneId]) => { + expect(id).toEqual('test-common-stack-site-record-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/dnsRecord:DnsRecord::test-common-stack-site-record' + ) + expect(name).toEqual('test.app') + expect(ttl).toEqual(300) + expect(type).toEqual('CNAME') + expect(content).toEqual('example.gradientedge.io') + expect(zoneId).toEqual('test-common-stack-site-record-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/construct/pages-static-site.test.ts1 b/src/test/cloudflare/construct/pages-static-site.test.ts1 deleted file mode 100644 index 2512dd99..00000000 --- a/src/test/cloudflare/construct/pages-static-site.test.ts1 +++ /dev/null @@ -1,179 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CloudflarePagesStaticSite, - CloudflarePagesStaticSiteProps, - CommonCloudflareStack, - CommonCloudflareStackProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CloudflarePagesStaticSiteProps { - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/pages.json', - 'src/test/cloudflare/common/cdkConfig/record.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - siteAssetDir: `src/test/cloudflare/common/sample.html`, - siteCnameRecord: this.node.tryGetContext('testCNameRecord'), - sitePagesProject: this.node.tryGetContext('testPagesProject'), - siteSubDomain: `test.app`, - siteZone: this.node.tryGetContext('testZone'), - testAttribute: this.node.tryGetContext('testAttribute'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - } - } -} - -class TestCommonConstruct extends CloudflarePagesStaticSite { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - - this.initResources() - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflarePagesStaticSite', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-common-stack-zone') - }) -}) - -describe('TestCloudflarePagesStaticSite', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflarePagesStaticSite', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflarePagesStaticSite', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testCommonStackSiteDomainPagesDomainFriendlyUniqueId: { value: 'test-common-stack-site-domain' }, - testCommonStackSiteDomainPagesDomainId: { - value: '${cloudflare_pages_domain.test-common-stack-site-domain.id}', - }, - testCommonStackSiteProjectPagesProjectFriendlyUniqueId: { value: 'test-common-stack-site-project' }, - testCommonStackSiteProjectPagesProjectId: { - value: '${cloudflare_pages_project.test-common-stack-site-project.id}', - }, - testCommonStackSiteRecordRecordFriendlyUniqueId: { value: 'test-common-stack-site-record' }, - testCommonStackSiteRecordRecordId: { value: '${cloudflare_dns_record.test-common-stack-site-record.id}' }, - testCommonStackZoneZoneFriendlyUniqueId: { value: 'test-common-stack-zone' }, - testCommonStackZoneZoneId: { value: '${cloudflare_zone.test-common-stack-zone.id}' }, - testCommonStackZoneZoneName: { value: '${cloudflare_zone.test-common-stack-zone.name}' }, - }) - }) -}) - -describe('TestCloudflarePagesStaticSite', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflarePagesStaticSite', () => { - test('provisions pages project as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'PagesProject', { - account_id: '${var.accountId}', - name: 'test-simple-project-dev', - production_branch: 'main', - }) - ) - }) -}) - -describe('TestCloudflarePagesStaticSite', () => { - test('provisions pages domain as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'PagesDomain', { - account_id: '${var.accountId}', - name: 'test.app.gradientedge.io', - project_name: '${cloudflare_pages_project.test-common-stack-site-project.name}', - }) - ) - }) -}) - -describe('TestCloudflarePagesStaticSite', () => { - test('provisions cname record as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'DnsRecord', { - content: 'example.gradientedge.io', - data: { - value: '${cloudflare_pages_project.test-common-stack-site-project.name}.pages.dev', - }, - name: 'test.app', - ttl: 300, - type: 'CNAME', - zone_id: '${data.cloudflare_zone.test-common-stack-site-record-data-zone-data-zone.zone_id}', - }) - ) - }) -}) diff --git a/src/test/cloudflare/construct/worker-site.test.ts b/src/test/cloudflare/construct/worker-site.test.ts new file mode 100644 index 00000000..cda7b8b3 --- /dev/null +++ b/src/test/cloudflare/construct/worker-site.test.ts @@ -0,0 +1,202 @@ +import * as pulumi from '@pulumi/pulumi' +import { + CloudflareWorkerSite, + CloudflareWorkerSiteProps, + CommonCloudflareStack, +} from '../../../lib/cloudflare/index.js' + +interface TestCloudflareStackProps extends CloudflareWorkerSiteProps { + testAttribute?: string +} + +const testStackProps: any = { + accountId: '123456789012', + domainName: 'gradientedge.io', + extraContexts: [ + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/rule-set.json', + 'src/test/cloudflare/common/config/worker.json', + 'src/test/cloudflare/common/config/zone.json', + ], + features: {}, + name: 'test-common-stack', + skipStageForARecords: false, + stage: 'dev', + stageContextPath: 'src/test/cloudflare/common/env', +} + +class TestCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + declare construct: TestCommonConstruct + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: TestCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + siteWorkerAsset: `src/test/cloudflare/common/sample.html`, + siteSubDomain: `test.app`, + } + } +} + +class TestInvalidCommonCloudflareStack extends CommonCloudflareStack { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, testStackProps) + this.construct = new TestCommonConstruct(props.name, this.props) + } + + protected determineConstructProps(props: TestCloudflareStackProps) { + return { + ...super.determineConstructProps(props), + siteWorkerDomain: undefined, + } + } +} + +class TestCommonConstruct extends CloudflareWorkerSite { + declare props: TestCloudflareStackProps + + constructor(name: string, props: TestCloudflareStackProps) { + super(name, props) + this.initResources() + } +} + +pulumi.runtime.setMocks({ + newResource: (args: pulumi.runtime.MockResourceArgs) => { + return { + id: `${args.name}-id`, + state: args.inputs, + } + }, + call: (args: pulumi.runtime.MockCallArgs) => { + return args.inputs + }, +}) + +let stack = new TestCommonCloudflareStack('test-stack', testStackProps) + +describe('TestCloudflareWorkerSite', () => { + test('handles mis-configurations as expected', () => { + expect(() => new TestInvalidCommonCloudflareStack('test-stack', testStackProps)).toThrow() + }) +}) + +describe('TestCloudflareWorkerSite', () => { + expect(stack.construct.siteZone).toBeDefined() + test('provisions zone as expected', () => { + pulumi + .all([ + stack.construct.siteZone.id, + stack.construct.siteZone.urn, + stack.construct.siteZone.name, + stack.construct.siteZone.account, + ]) + .apply(([id, urn, name, account]) => { + expect(id).toEqual('test-common-stack-zone-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/zone:Zone::test-common-stack-zone') + expect(name).toEqual('gradientedge.io') + expect(account.id).toEqual('test-account') + }) + }) +}) + +describe('TestCloudflareWorkerSite', () => { + expect(stack.construct.siteWorkerScript).toBeDefined() + test('provisions worker script as expected', () => { + pulumi + .all([ + stack.construct.siteWorkerScript.id, + stack.construct.siteWorkerScript.urn, + stack.construct.siteWorkerScript.accountId, + stack.construct.siteWorkerScript.bindings, + stack.construct.siteWorkerScript.content, + stack.construct.siteWorkerScript.scriptName, + ]) + .apply(([id, urn, accountId, bindings, content, scriptName]) => { + expect(id).toEqual('test-common-stack-worker-script-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/workersScript:WorkersScript::test-common-stack-worker-script' + ) + expect(accountId).toEqual('test-account') + expect(bindings).toEqual([]) + expect(content).toBeDefined() + expect(scriptName).toEqual('test-script-dev') + }) + }) +}) + +describe('TestCloudflareWorkerSite', () => { + expect(stack.construct.siteWorkerDomain).toBeDefined() + test('provisions workers custom domain as expected', () => { + pulumi + .all([ + stack.construct.siteWorkerDomain.id, + stack.construct.siteWorkerDomain.urn, + stack.construct.siteWorkerDomain.accountId, + stack.construct.siteWorkerDomain.hostname, + stack.construct.siteWorkerDomain.service, + stack.construct.siteWorkerDomain.zoneId, + ]) + .apply(([id, urn, accountId, hostname, service, zoneId]) => { + expect(id).toEqual('test-common-stack-worker-domain-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/workersCustomDomain:WorkersCustomDomain::test-common-stack-worker-domain' + ) + expect(accountId).toEqual('test-account') + expect(hostname).toEqual('test.app.gradientedge.io') + expect(service).toEqual('test-script-dev') + expect(zoneId).toEqual('test-common-stack-worker-domain-data-zone') + }) + }) +}) + +describe('TestCloudflareWorkerSite', () => { + expect(stack.construct.siteRuleSet).toBeDefined() + test('provisions ruleset as expected', () => { + pulumi + .all([ + stack.construct.siteRuleSet.id, + stack.construct.siteRuleSet.urn, + stack.construct.siteRuleSet.name, + stack.construct.siteRuleSet.rules, + ]) + .apply(([id, urn, name, rules]) => { + expect(id).toEqual('test-common-stack-rule-id') + expect(urn).toEqual('urn:pulumi:stack::project::cloudflare:index/ruleset:Ruleset::test-common-stack-rule') + expect(name).toEqual('testRuleSet') + expect(rules).toEqual({ + action: 'set_cache_settings', + }) + }) + }) +}) + +describe('TestCloudflareWorkerSite', () => { + expect(stack.construct.siteZoneSetting).toBeDefined() + test('provisions zone settings override as expected', () => { + pulumi + .all([ + stack.construct.siteZoneSetting.id, + stack.construct.siteZoneSetting.urn, + stack.construct.siteZoneSetting.settingId, + stack.construct.siteZoneSetting.value, + stack.construct.siteZoneSetting.zoneId, + ]) + .apply(([id, urn, settingId, value, zoneId]) => { + expect(id).toEqual('test-common-stack-zone-setting-id') + expect(urn).toEqual( + 'urn:pulumi:stack::project::cloudflare:index/zoneSetting:ZoneSetting::test-common-stack-zone-setting' + ) + expect(settingId).toEqual('always_online') + expect(value).toEqual('on') + expect(zoneId).toEqual('test-common-stack-zone-setting-data-zone') + }) + }) +}) diff --git a/src/test/cloudflare/construct/worker-site.test.ts1 b/src/test/cloudflare/construct/worker-site.test.ts1 deleted file mode 100644 index 2156d2e3..00000000 --- a/src/test/cloudflare/construct/worker-site.test.ts1 +++ /dev/null @@ -1,182 +0,0 @@ -import { App, Testing } from 'cdktf' -import 'cdktf/lib/testing/adapters/jest' -import { Construct } from 'constructs' -import { - CloudflareWorkerSite, - CloudflareWorkerSiteProps, - CommonCloudflareStack, - CommonCloudflareStackProps, -} from '../../../lib/cloudflare/index.js' - -interface TestCloudflareStackProps extends CloudflareWorkerSiteProps { - testAttribute?: string -} - -const testStackProps: any = { - accountId: '123456789012', - domainName: 'gradientedge.io', - extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/rule-set.json', - 'src/test/cloudflare/common/cdkConfig/worker.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', - ], - features: {}, - name: 'test-common-stack', - skipStageForARecords: false, - stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', -} - -class TestCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - siteWorkerAsset: `src/test/cloudflare/common/sample.html`, - siteWorkerDomain: this.node.tryGetContext('testWorkerDomain'), - siteRuleSet: this.node.tryGetContext('testRuleSet'), - siteSubDomain: `test.app`, - siteWorkerScript: this.node.tryGetContext('testWorkerScript'), - siteZone: this.node.tryGetContext('testZone'), - siteZoneSetting: this.node.tryGetContext('testZoneSetting'), - testAttribute: this.node.tryGetContext('testAttribute'), - } - } -} - -class TestInvalidCommonStack extends CommonCloudflareStack { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, testStackProps) - this.construct = new TestCommonConstruct(this, props.name, this.props) - } - - protected determineConstructProps(props: CommonCloudflareStackProps) { - return { - ...super.determineConstructProps(props), - testAttribute: this.node.tryGetContext('testAttribute'), - } - } -} - -class TestCommonConstruct extends CloudflareWorkerSite { - declare props: TestCloudflareStackProps - - constructor(parent: Construct, name: string, props: TestCloudflareStackProps) { - super(parent, name, props) - - this.initResources() - } -} - -const app = new App({ context: testStackProps }) -const testingApp = Testing.fakeCdktfJsonPath(app) -const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps) -const stack = Testing.fullSynth(commonStack) -const construct = Testing.synth(commonStack.construct) - -describe('TestCloudflareWorkerSite', () => { - test('handles mis-configurations as expected', () => { - const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps) - expect(error).toThrow('Props undefined for test-common-stack-zone') - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('is initialised as expected', () => { - /* test if the created stack have the right properties injected */ - expect(commonStack.props).toHaveProperty('testAttribute') - expect(commonStack.props.testAttribute).toEqual('success') - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('synthesises as expected', () => { - expect(stack).toBeDefined() - expect(construct).toBeDefined() - expect(Testing.toBeValidTerraform(stack)).toBeTruthy() - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('provisions outputs as expected', () => { - expect(JSON.parse(construct).output).toMatchObject({ - testCommonStackZoneZoneFriendlyUniqueId: { value: 'test-common-stack-zone' }, - testCommonStackZoneZoneId: { value: '${cloudflare_zone.test-common-stack-zone.id}' }, - testCommonStackZoneZoneName: { value: '${cloudflare_zone.test-common-stack-zone.name}' }, - }) - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('provisions zone as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Zone', { - account: { - id: 'test-account', - }, - name: 'gradientedge.io', - }) - ) - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('provisions worker as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersScript', { - account_id: 'test-account', - bindings: [], - content: '${file("assets/test-common-stack-worker-content/DBA9E2ED0784B0A520C0C26867C9B2FF/sample.html")}', - script_name: 'test-script-dev', - }) - ) - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('provisions worker domain as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'WorkersCustomDomain', { - account_id: 'test-account', - hostname: 'test.app.gradientedge.io', - service: '${cloudflare_workers_script.test-common-stack-worker-script.script_name}', - zone_id: '${data.cloudflare_zone.test-common-stack-worker-domain-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('provisions Rule Set as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'Ruleset', { - name: 'testRuleSet', - rules: { - action: 'set_cache_settings', - }, - zone_id: '${data.cloudflare_zone.test-common-stack-rule-data-zone-data-zone.zone_id}', - }) - ) - }) -}) - -describe('TestCloudflareWorkerSite', () => { - test('provisions zone settings override as expected', () => { - expect( - Testing.toHaveResourceWithProperties(construct, 'ZoneSetting', { - setting_id: 'always_online', - value: 'on', - zone_id: '${data.cloudflare_zone.test-common-stack-zone-setting-data-zone-data-zone.id}', - }) - ) - }) -}) diff --git a/src/test/cloudflare/services/access-manager.test.ts b/src/test/cloudflare/services/access-manager.test.ts index 7bf0bb7c..477b1410 100644 --- a/src/test/cloudflare/services/access-manager.test.ts +++ b/src/test/cloudflare/services/access-manager.test.ts @@ -52,14 +52,14 @@ const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/access.json', - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', + 'src/test/cloudflare/common/config/access.json', + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/zone.json', ], name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/api-shield-manager.test.ts b/src/test/cloudflare/services/api-shield-manager.test.ts index ab99d66e..50be8bb2 100644 --- a/src/test/cloudflare/services/api-shield-manager.test.ts +++ b/src/test/cloudflare/services/api-shield-manager.test.ts @@ -34,15 +34,15 @@ const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/api-shield.json', - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', + 'src/test/cloudflare/common/config/api-shield.json', + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/zone.json', ], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/argo-manager.test.ts b/src/test/cloudflare/services/argo-manager.test.ts index dc73bd77..b26dd128 100644 --- a/src/test/cloudflare/services/argo-manager.test.ts +++ b/src/test/cloudflare/services/argo-manager.test.ts @@ -18,15 +18,15 @@ const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/argo.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/argo.json', + 'src/test/cloudflare/common/config/zone.json', ], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/firewall-manager.test.ts b/src/test/cloudflare/services/firewall-manager.test.ts index 44b1a91b..36c42508 100644 --- a/src/test/cloudflare/services/firewall-manager.test.ts +++ b/src/test/cloudflare/services/firewall-manager.test.ts @@ -20,16 +20,16 @@ const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/filter.json', - 'src/test/cloudflare/common/cdkConfig/firewall.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/filter.json', + 'src/test/cloudflare/common/config/firewall.json', + 'src/test/cloudflare/common/config/zone.json', ], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/page-manager.test.ts b/src/test/cloudflare/services/page-manager.test.ts index b7e3713f..8e149d24 100644 --- a/src/test/cloudflare/services/page-manager.test.ts +++ b/src/test/cloudflare/services/page-manager.test.ts @@ -22,12 +22,12 @@ interface TestCloudflareStackProps extends CommonCloudflareStackProps { const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', - extraContexts: ['src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/pages.json'], + extraContexts: ['src/test/cloudflare/common/config/dummy.json', 'src/test/cloudflare/common/config/pages.json'], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/record-manager.test.ts b/src/test/cloudflare/services/record-manager.test.ts index d4f356a2..06c25d3e 100644 --- a/src/test/cloudflare/services/record-manager.test.ts +++ b/src/test/cloudflare/services/record-manager.test.ts @@ -19,15 +19,15 @@ const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/record.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/record.json', + 'src/test/cloudflare/common/config/zone.json', ], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/rule-set-manager.test.ts b/src/test/cloudflare/services/rule-set-manager.test.ts index 0d0da032..af10aa14 100644 --- a/src/test/cloudflare/services/rule-set-manager.test.ts +++ b/src/test/cloudflare/services/rule-set-manager.test.ts @@ -18,15 +18,15 @@ const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/rule-set.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/rule-set.json', + 'src/test/cloudflare/common/config/zone.json', ], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/worker-manager.test.ts b/src/test/cloudflare/services/worker-manager.test.ts index e7023b63..befbe3bc 100644 --- a/src/test/cloudflare/services/worker-manager.test.ts +++ b/src/test/cloudflare/services/worker-manager.test.ts @@ -38,15 +38,15 @@ const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', extraContexts: [ - 'src/test/cloudflare/common/cdkConfig/dummy.json', - 'src/test/cloudflare/common/cdkConfig/worker.json', - 'src/test/cloudflare/common/cdkConfig/zone.json', + 'src/test/cloudflare/common/config/dummy.json', + 'src/test/cloudflare/common/config/worker.json', + 'src/test/cloudflare/common/config/zone.json', ], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/src/test/cloudflare/services/zone-manager.test.ts b/src/test/cloudflare/services/zone-manager.test.ts index 7ed99151..749a3863 100644 --- a/src/test/cloudflare/services/zone-manager.test.ts +++ b/src/test/cloudflare/services/zone-manager.test.ts @@ -29,12 +29,12 @@ interface TestCloudflareStackProps extends CommonCloudflareStackProps { const testStackProps: any = { accountId: '123456789012', domainName: 'gradientedge.io', - extraContexts: ['src/test/cloudflare/common/cdkConfig/dummy.json', 'src/test/cloudflare/common/cdkConfig/zone.json'], + extraContexts: ['src/test/cloudflare/common/config/dummy.json', 'src/test/cloudflare/common/config/zone.json'], features: {}, name: 'test-common-stack', skipStageForARecords: false, stage: 'dev', - stageContextPath: 'src/test/aws/common/cdkEnv', + stageContextPath: 'src/test/cloudflare/common/env', } class TestCommonCloudflareStack extends CommonCloudflareStack { diff --git a/tsconfig.json b/tsconfig.json index 2b1ca2a8..39ff368f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -37,8 +37,8 @@ "src/test/cloudflare/services/argo-manager.test.ts", "src/test/cloudflare/services/api-shield-manager.test.ts", "src/test/cloudflare/services/access-manager.pulumi.test.ts1", - "src/test/cloudflare/construct/worker-site.test.ts1", - "src/test/cloudflare/construct/pages-static-site.test.ts1", - "src/test/cloudflare/common/common-cloudflare-construct.test.ts1" + "src/test/cloudflare/construct/worker-site.test.ts", + "src/test/cloudflare/construct/pages-static-site.test.ts", + "src/test/cloudflare/common/common-cloudflare-construct.test.ts" ] }