diff --git a/.gitignore b/.gitignore index 8fac46d..0d95660 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ -/.idea/ -/node_modules/ -/dist/ -/coverage/ -/.vscode/ +.idea/ +node_modules/ +dist/ +coverage/ +.vscode/ .DS_Store -/artifacts/ +artifacts/ diff --git a/layers/si-bootstrap-sdk/Dockerfile b/layers/si-bootstrap-sdk/Dockerfile new file mode 100644 index 0000000..7092392 --- /dev/null +++ b/layers/si-bootstrap-sdk/Dockerfile @@ -0,0 +1,19 @@ +FROM node:18.20.3-buster-slim@sha256:95fb3cf1d1ab1834c0fd65cdd2246198662460ae8f982a6cfab187889dd54bbe AS builder +WORKDIR /app + +ENV NODE_ENV=development +COPY ./package.json . +COPY ./package-lock.json . +RUN npm install +COPY ./tsconfig.json . +COPY ./src ./src +RUN npm run build + +FROM node:18.20.3-buster-slim@sha256:95fb3cf1d1ab1834c0fd65cdd2246198662460ae8f982a6cfab187889dd54bbe +WORKDIR /app + +ENV NODE_ENV=production +COPY --from=builder /app/dist . +COPY ./package.json . +COPY ./package-lock.json . +RUN npm install diff --git a/layers/si-bootstrap-sdk/Dockerfile-aliyuncli b/layers/si-bootstrap-sdk/Dockerfile-aliyuncli new file mode 100644 index 0000000..30abfed --- /dev/null +++ b/layers/si-bootstrap-sdk/Dockerfile-aliyuncli @@ -0,0 +1,12 @@ +FROM alpine:latest + +RUN apk update && apk add --no-cache jq + +# install aliyuncli +RUN wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz +RUN tar -xvzf aliyun-cli-linux-latest-amd64.tgz +RUN rm aliyun-cli-linux-latest-amd64.tgz +RUN mv aliyun /usr/local/bin/ + +# 注意:alpine需要额外创建 lib64 的动态链接库软连接 +RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 diff --git a/layers/si-bootstrap-sdk/README.md b/layers/si-bootstrap-sdk/README.md new file mode 100644 index 0000000..78140af --- /dev/null +++ b/layers/si-bootstrap-sdk/README.md @@ -0,0 +1 @@ +# ServerlessInsight bootstrap SDK diff --git a/layers/si-bootstrap-sdk/package-lock.json b/layers/si-bootstrap-sdk/package-lock.json new file mode 100644 index 0000000..898c29b --- /dev/null +++ b/layers/si-bootstrap-sdk/package-lock.json @@ -0,0 +1,875 @@ +{ + "name": "@geek-fun/si-bootstrap-sdk", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@geek-fun/si-bootstrap-sdk", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/credentials": "^2.4.4", + "@alicloud/openapi-client": "^0.4.15", + "@alicloud/tablestore20201209": "^1.2.0", + "pino": "^9.8.0", + "pino-pretty": "^13.1.1", + "tablestore": "^5.6.1" + }, + "devDependencies": { + "@types/tablestore": "^5.1.3", + "typescript": "^5.9.2" + } + }, + "node_modules/@alicloud/credentials": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@alicloud/credentials/-/credentials-2.4.4.tgz", + "integrity": "sha512-/eRAGSKcniLIFQ1UCpDhB/IrHUZisQ1sc65ws/c2avxUMpXwH1rWAohb76SVAUJhiF4mwvLzLJM1Mn1XL4Xe/Q==", + "license": "MIT", + "dependencies": { + "@alicloud/tea-typescript": "^1.8.0", + "httpx": "^2.3.3", + "ini": "^1.3.5", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/darabonba-array": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-array/-/darabonba-array-0.1.1.tgz", + "integrity": "sha512-UPP7p9//jywqM8EN6BjSbw1ovl/BzqreXdi5FmxT6m3PmFxsxabe+yamjeopyf2Gi0p3WqwJTBCeNji5eYUsJw==", + "license": "ISC", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "node_modules/@alicloud/darabonba-encode-util": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-encode-util/-/darabonba-encode-util-0.0.2.tgz", + "integrity": "sha512-mlsNctkeqmR0RtgE1Rngyeadi5snLOAHBCWEtYf68d7tyKskosXDTNeZ6VCD/UfrUu4N51ItO8zlpfXiOgeg3A==", + "license": "ISC", + "dependencies": { + "moment": "^2.29.1" + } + }, + "node_modules/@alicloud/darabonba-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-map/-/darabonba-map-0.0.1.tgz", + "integrity": "sha512-2ep+G3YDvuI+dRYVlmER1LVUQDhf9kEItmVB/bbEu1pgKzelcocCwAc79XZQjTcQGFgjDycf3vH87WLDGLFMlw==", + "license": "ISC", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "node_modules/@alicloud/darabonba-signature-util": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-signature-util/-/darabonba-signature-util-0.0.4.tgz", + "integrity": "sha512-I1TtwtAnzLamgqnAaOkN0IGjwkiti//0a7/auyVThdqiC/3kyafSAn6znysWOmzub4mrzac2WiqblZKFcN5NWg==", + "license": "ISC", + "dependencies": { + "@alicloud/darabonba-encode-util": "^0.0.1" + } + }, + "node_modules/@alicloud/darabonba-signature-util/node_modules/@alicloud/darabonba-encode-util": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-encode-util/-/darabonba-encode-util-0.0.1.tgz", + "integrity": "sha512-Sl5vCRVAYMqwmvXpJLM9hYoCHOMsQlGxaWSGhGWulpKk/NaUBArtoO1B0yHruJf1C5uHhEJIaylYcM48icFHgw==", + "license": "ISC", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1", + "moment": "^2.29.1" + } + }, + "node_modules/@alicloud/darabonba-string": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-string/-/darabonba-string-1.0.3.tgz", + "integrity": "sha512-NyWwrU8cAIesWk3uHL1Q7pTDTqLkCI/0PmJXC4/4A0MFNAZ9Ouq0iFBsRqvfyUujSSM+WhYLuTfakQXiVLkTMA==", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1" + } + }, + "node_modules/@alicloud/endpoint-util": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/endpoint-util/-/endpoint-util-0.0.1.tgz", + "integrity": "sha512-+pH7/KEXup84cHzIL6UJAaPqETvln4yXlD9JzlrqioyCSaWxbug5FUobsiI6fuUOpw5WwoB3fWAtGbFnJ1K3Yg==", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/gateway-pop": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@alicloud/gateway-pop/-/gateway-pop-0.0.6.tgz", + "integrity": "sha512-KF4I+JvfYuLKc3fWeWYIZ7lOVJ9jRW0sQXdXidZn1DKZ978ncfGf7i0LBfONGk4OxvNb/HD3/0yYhkgZgPbKtA==", + "license": "ISC", + "dependencies": { + "@alicloud/credentials": "^2", + "@alicloud/darabonba-array": "^0.1.0", + "@alicloud/darabonba-encode-util": "^0.0.2", + "@alicloud/darabonba-map": "^0.0.1", + "@alicloud/darabonba-signature-util": "^0.0.4", + "@alicloud/darabonba-string": "^1.0.2", + "@alicloud/endpoint-util": "^0.0.1", + "@alicloud/gateway-spi": "^0.0.8", + "@alicloud/openapi-util": "^0.3.2", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.4.8" + } + }, + "node_modules/@alicloud/gateway-spi": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@alicloud/gateway-spi/-/gateway-spi-0.0.8.tgz", + "integrity": "sha512-KM7fu5asjxZPmrz9sJGHJeSU+cNQNOxW+SFmgmAIrITui5hXL2LB+KNRuzWmlwPjnuA2X3/keq9h6++S9jcV5g==", + "license": "ISC", + "dependencies": { + "@alicloud/credentials": "^2", + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "node_modules/@alicloud/openapi-client": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-client/-/openapi-client-0.4.15.tgz", + "integrity": "sha512-4VE0/k5ZdQbAhOSTqniVhuX1k5DUeUMZv74degn3wIWjLY6Bq+hxjaGsaHYlLZ2gA5wUrs8NcI5TE+lIQS3iiA==", + "license": "ISC", + "dependencies": { + "@alicloud/credentials": "^2.4.2", + "@alicloud/gateway-spi": "^0.0.8", + "@alicloud/openapi-util": "^0.3.2", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "1.4.9", + "@alicloud/tea-xml": "0.0.3" + } + }, + "node_modules/@alicloud/openapi-client/node_modules/@alicloud/tea-util": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/@alicloud/tea-util/-/tea-util-1.4.9.tgz", + "integrity": "sha512-S0wz76rGtoPKskQtRTGqeuqBHFj8BqUn0Vh+glXKun2/9UpaaaWmuJwcmtImk6bJZfLYEShDF/kxDmDJoNYiTw==", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/openapi-core": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-core/-/openapi-core-1.0.4.tgz", + "integrity": "sha512-e9WK1lKiMOOziuLgNaYWv7FL50FyrcpO+idoLhNmFR7k0Fax4lPht5suBpTBr1PSINg5R1W3eOCm5vaUTrY4lg==", + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "@alicloud/credentials": "latest", + "@alicloud/gateway-pop": "0.0.6", + "@alicloud/gateway-spi": "^0.0.8", + "@darabonba/typescript": "^1.0.2" + } + }, + "node_modules/@alicloud/openapi-util": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-util/-/openapi-util-0.3.2.tgz", + "integrity": "sha512-EC2JvxdcOgMlBAEG0+joOh2IB1um8CPz9EdYuRfTfd1uP8Yc9D8QRUWVGjP6scnj6fWSOaHFlit9H6PrJSyFow==", + "license": "ISC", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.3.0", + "kitx": "^2.1.0", + "sm3": "^1.0.3" + } + }, + "node_modules/@alicloud/tablestore20201209": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@alicloud/tablestore20201209/-/tablestore20201209-1.2.0.tgz", + "integrity": "sha512-e+2TgAlESETR9aBpjJsnIN7/MOvQoV2UkgL9b3wFCH+yJ0ZBvsGqwybC5XHqjsr8R9cgRa6fomTzPCqUD1D8IA==", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/openapi-core": "^1.0.0", + "@darabonba/typescript": "^1.0.0" + } + }, + "node_modules/@alicloud/tea-typescript": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/tea-typescript/-/tea-typescript-1.8.0.tgz", + "integrity": "sha512-CWXWaquauJf0sW30mgJRVu9aaXyBth5uMBCUc+5vKTK1zlgf3hIqRUjJZbjlwHwQ5y9anwcu18r48nOZb7l2QQ==", + "license": "ISC", + "dependencies": { + "@types/node": "^12.0.2", + "httpx": "^2.2.6" + } + }, + "node_modules/@alicloud/tea-util": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@alicloud/tea-util/-/tea-util-1.4.10.tgz", + "integrity": "sha512-VEsXWP2dlJLvsY2THj+sH++zwxQRz3Y5BQ8EkfnFems36RkngQKYOLsoto5nR6ej1Gf6I+0IOgBXrkRdpNCQ1g==", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "@darabonba/typescript": "^1.0.0", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/tea-xml": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@alicloud/tea-xml/-/tea-xml-0.0.3.tgz", + "integrity": "sha512-+/9GliugjrLglsXVrd1D80EqqKgGpyA0eQ6+1ZdUOYCaRguaSwz44trX3PaxPu/HhIPJg9PsGQQ3cSLXWZjbAA==", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/tea-typescript": "^1", + "@types/xml2js": "^0.4.5", + "xml2js": "^0.6.0" + } + }, + "node_modules/@darabonba/typescript": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@darabonba/typescript/-/typescript-1.0.3.tgz", + "integrity": "sha512-/y2y6wf5TsxD7pCPIm0OvTC+5qV0Tk7HQYxwpIuWRLXQLB0CRDvr6qk4bR6rTLO/JglJa8z2uCGZsaLYpQNqFQ==", + "license": "Apache License 2.0", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "httpx": "^2.3.2", + "lodash": "^4.17.21", + "moment": "^2.30.1", + "moment-timezone": "^0.5.45", + "xml2js": "^0.6.2" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "license": "MIT" + }, + "node_modules/@types/tablestore": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/tablestore/-/tablestore-5.1.3.tgz", + "integrity": "sha512-/G+o91ZMrMlUueZY9BqxnrSpT8PyDc5uytTlsvIkvrPhF6V50Jr5xH8r0NLjD0aCiAHVheQVlpTuFe1OKVPdgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/xml2js": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz", + "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha512-DNK4ruAqtyHaN8Zne7PkBTO+dD1Lr0YfTduMqlIyjvQIoztBkUxrvL+hKeLW8NXFKHOq/2upkxuoS9znQ9bW9A==", + "deprecated": "This version of 'buffer' is out-of-date. You must update to v4.9.2 or newer", + "license": "MIT", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/fast-copy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", + "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", + "license": "MIT" + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==", + "license": "SEE LICENSE IN LICENSE.txt" + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "license": "MIT" + }, + "node_modules/httpx": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/httpx/-/httpx-2.3.3.tgz", + "integrity": "sha512-k1qv94u1b6e+XKCxVbLgYlOypVP9MPGpnN5G/vxFf6tDO4V3xpz3d6FUOY/s8NtPgaq5RBVVgSB+7IHpVxMYzw==", + "license": "MIT", + "dependencies": { + "@types/node": "^20", + "debug": "^4.1.1" + } + }, + "node_modules/httpx/node_modules/@types/node": { + "version": "20.19.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.9.tgz", + "integrity": "sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/int64-buffer": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.9.tgz", + "integrity": "sha512-hTYImck2Z72PmEbnKi7zgRvpkeAHIK0ggY01l89GbglIx3B+BYt5Ef2ospIX/2W/cRaBFH99xL5VnWJQsavAtg==", + "license": "MIT" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/kitx": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/kitx/-/kitx-2.2.0.tgz", + "integrity": "sha512-tBMwe6AALTBQJb0woQDD40734NKzb0Kzi3k7wQj9ar3AbP9oqhoVrdXPh7rk2r00/glIgd0YbToIUJsnxWMiIg==", + "license": "MIT", + "dependencies": { + "@types/node": "^22.5.4" + } + }, + "node_modules/kitx/node_modules/@types/node": { + "version": "22.17.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.0.tgz", + "integrity": "sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pino": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.8.0.tgz", + "integrity": "sha512-L5+rV1wL7vGAcxXP7sPpN5lrJ07Piruka6ArXr7EWBXxdVWjJshGVX8suFsiusJVcGKDGUFfbgbnKdg+VAC+0g==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.1.1.tgz", + "integrity": "sha512-TNNEOg0eA0u+/WuqH0MH0Xui7uqVk9D74ESOpjtebSQYbNWJk/dIxCXIxFsNfeN53JmtWqYHP2OrIZjT/CBEnA==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.2", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pump": "^3.0.0", + "secure-json-parse": "^4.0.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^5.0.2" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "license": "MIT" + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "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/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/@types/node": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.0.tgz", + "integrity": "sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/protobufjs/node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, + "node_modules/secure-json-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz", + "integrity": "sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/sm3": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sm3/-/sm3-1.0.3.tgz", + "integrity": "sha512-KyFkIfr8QBlFG3uc3NaljaXdYcsbRy1KrSfc4tsQV8jW68jAktGeOcifu530Vx/5LC+PULHT0Rv8LiI8Gw+c1g==", + "license": "MIT" + }, + "node_modules/sonic-boom": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", + "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/strip-json-comments": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.2.tgz", + "integrity": "sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tablestore": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/tablestore/-/tablestore-5.6.1.tgz", + "integrity": "sha512-3SRuf/9J13bFTIxi9bmp7s28Oh/IUd7gPDIyNzkGdh4/p4GR8iuTTGViVniMr94mkRj6K95osPQdTFy1YqUOdw==", + "license": "Apache-2.0", + "dependencies": { + "buffer": "4.9.1", + "flatbuffers": "^1.5.0", + "int64-buffer": "0.1.9", + "protobufjs": "^6.11.3" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", + "engines": { + "node": ">=4.0" + } + } + } +} diff --git a/layers/si-bootstrap-sdk/package.json b/layers/si-bootstrap-sdk/package.json new file mode 100644 index 0000000..b9e582d --- /dev/null +++ b/layers/si-bootstrap-sdk/package.json @@ -0,0 +1,33 @@ +{ + "name": "@geek-fun/si-bootstrap-sdk", + "version": "1.0.0", + "main": "src/index.js", + "types": "src/index.d.ts", + "description": "Bootstrap SDK for Serverless Insight", + "homepage": "https://serverlessinsight.geekfun.club", + "scripts": { + "build": "tsc --build", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/geek-fun/serverlessinsight.git" + }, + "author": "geekfun ", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/geek-fun/serverlessinsight/issues" + }, + "devDependencies": { + "@types/tablestore": "^5.1.3", + "typescript": "^5.9.2" + }, + "dependencies": { + "@alicloud/credentials": "^2.4.4", + "@alicloud/openapi-client": "^0.4.15", + "@alicloud/tablestore20201209": "^1.2.0", + "pino": "^9.8.0", + "pino-pretty": "^13.1.1", + "tablestore": "^5.6.1" + } +} diff --git a/layers/si-bootstrap-sdk/scripts/aliyuncli.sh b/layers/si-bootstrap-sdk/scripts/aliyuncli.sh new file mode 100755 index 0000000..32ed59a --- /dev/null +++ b/layers/si-bootstrap-sdk/scripts/aliyuncli.sh @@ -0,0 +1,15 @@ +#!/bin/bash -eu +set -o pipefail + +cd "$(dirname "$0")/.." || exit + +ALIYUN_REGION=${ALIYUN_REGION:-cn-hangzhou} + + +docker build -t aliyuncli -f Dockerfile-aliyuncli .\ + && docker run -it --rm \ + --name aliyuncli aliyuncli aliyun \ + --region $ALIYUN_REGION \ + --access-key-id $ALIYUN_ACCESS_KEY_ID \ + --access-key-secret $ALIYUN_ACCESS_KEY_SECRET \ + "$@" diff --git a/layers/si-bootstrap-sdk/scripts/package.sh b/layers/si-bootstrap-sdk/scripts/package.sh new file mode 100755 index 0000000..8fdd618 --- /dev/null +++ b/layers/si-bootstrap-sdk/scripts/package.sh @@ -0,0 +1,22 @@ +#!/bin/bash -eux +set -o pipefail + +cd "$(dirname "$0")/.." || exit + +PACKAGE_NAME=$(jq -r '.name' package.json) + + +rm -rf ./dist ./artifacts/* + +mkdir -p "artifacts" +mkdir -p "dist/nodejs/node_modules/${PACKAGE_NAME}" + +IMAGE_NAME="si-bootstrap-sdk" +docker build -t "${IMAGE_NAME}" . + +docker run --rm \ + -v "$(pwd)"/dist:/dist \ + --name "${IMAGE_NAME}-package" "${IMAGE_NAME}:latest" \ + sh -c "cp -r /app/. /dist/nodejs/node_modules/${PACKAGE_NAME}" + +cd dist && zip -r -D "../artifacts/${IMAGE_NAME}.zip" ./* diff --git a/layers/si-bootstrap-sdk/scripts/publish-layer.sh b/layers/si-bootstrap-sdk/scripts/publish-layer.sh new file mode 100755 index 0000000..d4e0940 --- /dev/null +++ b/layers/si-bootstrap-sdk/scripts/publish-layer.sh @@ -0,0 +1,10 @@ +#!/bin/bash -eux +set -o pipefail + +cd "$(dirname "$0")/.." || exit + +SOURCE_CODE_BASE64=$(base64 -i ./artifacts/si-bootstrap-sdk.zip) + +ALIYUN_REGION="cn-hangzhou" ./scripts/aliyuncli.sh fc POST /2023-03-30/layers/si-bootstrap-sdk/versions \ + --header "Content-Type=application/json" \ + --body "{\"compatibleRuntime\":[\"nodejs20\",\"nodejs18\",\"nodejs16\"],\"code\":{\"zipFile\":\"${SOURCE_CODE_BASE64}\"},\"license\":\"Apache-2.0license\"}" diff --git a/layers/si-bootstrap-sdk/src/clients/index.ts b/layers/si-bootstrap-sdk/src/clients/index.ts new file mode 100644 index 0000000..9183805 --- /dev/null +++ b/layers/si-bootstrap-sdk/src/clients/index.ts @@ -0,0 +1,246 @@ +import Tablestore20201209, * as ots from '@alicloud/tablestore20201209'; +import { Config } from '@alicloud/credentials'; +import TableStore from 'tablestore'; +import * as teaUtil from '@alicloud/tea-util'; +import { Credentials } from '../tyes'; +import { formatOtsTableParam, logger } from '../common'; + +const loadAlicloudTableStoreClient = ( + region: string, + credentials: Credentials, +): Tablestore20201209 => { + const credentialsConfig = new Config({ ...credentials, type: 'access_key' }); + credentialsConfig.endpoint = `tablestore.${region}.aliyuncs.com`; + + return new Tablestore20201209(credentialsConfig); +}; + +const loadTableStore = ( + instanceName: string, + regionId: string, + credentials: Credentials, +): TableStore.Client => + new TableStore.Client({ + ...credentials, + endpoint: `https://${instanceName}.${regionId}.ots.aliyuncs.com`, + instancename: instanceName, + }); + +export const loadTableStoreClient = (regionId: string, credentials: Credentials) => { + const alicloudTableStoreClient = loadAlicloudTableStoreClient(regionId, credentials); + + return { + createInstance: async ({ + instanceName, + clusterType, + network, + tags: rawTags, + }: { + instanceName: string; + clusterType: string; + network: { + type: 'PRIVATE' | 'PUBLIC'; + vpcId?: string; + ingressRules: Array; + }; + tags?: Array<{ key: string; value: string }>; + }) => { + const tags = rawTags?.map( + (tag) => new ots.CreateInstanceRequestTags({ key: tag.key, value: tag.value }), + ); + const networkTypeACL = + network.type === 'PRIVATE' ? ['VPC'] : network.type === 'PUBLIC' ? ['PUBLIC'] : []; + + const createInstanceRequest = new ots.CreateInstanceRequest({ + instanceName: instanceName, + clusterType: clusterType, + networkTypeACL, + networkSourceACL: ['TRUST_PROXY', ...(network?.ingressRules ?? [])].filter(Boolean), + policy: '', + tags, + }); + + const runtime = new teaUtil.RuntimeOptions({}); + const headers: { [key: string]: string } = {}; + + try { + const response = await alicloudTableStoreClient.createInstanceWithOptions( + createInstanceRequest, + headers, + runtime, + ); + logger.info({ response, instanceName }, `Instance ${instanceName} created successfully`); + + if (!response?.body?.instanceName) { + throw new Error('Failed to create instance, response body is empty'); + } + + return { + instanceName: instanceName, + clusterType: response.body.clusterType, + instanceStatus: response.body.instanceStatus, + networkTypeACL: response.body.networkTypeACL, + networkSourceACL: response.body.networkSourceACL, + policy: response.body.policy, + }; + } catch (error) { + logger.error(error, 'Failed to create instance'); + throw error; + } + }, + + getInstance: async (instanceName: string) => { + const runtime = new teaUtil.RuntimeOptions({}); + const headers: { [key: string]: string } = {}; + const response = await alicloudTableStoreClient.getInstanceWithOptions( + new ots.GetInstanceRequest({ instanceName }), + headers, + runtime, + ); + if (!response?.body?.instanceName) { + return undefined; + } else { + return { + instanceName: response.body.instanceName, + clusterType: response.body.clusterType, + networkTypeACL: response.body.networkTypeACL, + networkSourceACL: response.body.networkSourceACL, + policy: response.body.policy, + instanceStatus: response.body.instanceStatus, + }; + } + }, + + createTable: async ({ + instanceName, + ...params + }: { + instanceName: string; + tableName: string; + primaryKey: Array<{ name: string; type: 'STRING' | 'INTEGER' | 'BINARY' }>; + columns: Array<{ + name: string; + type: 'STRING' | 'INTEGER' | 'DOUBLE' | 'BOOLEAN' | 'BINARY'; + }>; + reservedThroughput: { + read: number; + write: number; + }; + }) => { + const client = loadTableStore(instanceName, regionId, credentials); + const tableParam = formatOtsTableParam(params); + + await client.createTable(tableParam); + + return { + instanceName, + tableName: tableParam.tableMeta.tableName, + primaryKey: tableParam.tableMeta.primaryKey, + columns: tableParam.tableMeta.definedColumn, + reservedThroughput: tableParam.reservedThroughput, + }; + }, + + updateTable: async ({ + instanceName, + ...params + }: { + instanceName: string; + tableName: string; + primaryKey: Array<{ name: string; type: 'STRING' | 'INTEGER' | 'BINARY' }>; + columns: Array<{ + name: string; + type: 'STRING' | 'INTEGER' | 'DOUBLE' | 'BOOLEAN' | 'BINARY'; + }>; + reservedThroughput: { + read: number; + write: number; + }; + }) => { + const client = loadTableStore(instanceName, regionId, credentials); + const { + tableMeta: { tableName, primaryKey, definedColumn: columns }, + reservedThroughput, + } = formatOtsTableParam(params); + + const table = await client.describeTable({ tableName }); + if (!table?.tableMeta?.tableName) { + throw new Error(`Table ${tableName} does not exist in instance ${instanceName}`); + } + if (table?.tableMeta?.tableName !== tableName) { + throw new Error( + `Table name mismatch: expected ${tableName}, but got ${table?.tableMeta?.tableName}`, + ); + } + + const tableDiff = table.tableMeta.primaryKey.filter((pk) => + primaryKey.find(({ name, type }) => name === pk.name && type === pk.type), + ); + + if (tableDiff.length !== table.tableMeta.primaryKey.length) { + throw new Error( + `Primary update not support: expected ${JSON.stringify(table.tableMeta.primaryKey)}, but got ${JSON.stringify( + primaryKey, + )}`, + ); + } + + const columnsDiff = (table.tableMeta.definedColumn || []).reduce( + (acc, existingCol) => { + const matchingCol = columns.find((col) => col.name === existingCol.name); + + if (!matchingCol) { + // Column exists in table but not in new columns - delete + acc.deletedColumns.push(existingCol); + } else if (matchingCol.type !== existingCol.type) { + // Column exists in both but type is different + acc.typeChangedColumns.push(matchingCol); + } + + return acc; + }, + { + newColumns: columns.filter( + (col) => + !(table.tableMeta.definedColumn || []).find((existing) => existing.name === col.name), + ), + deletedColumns: [] as typeof table.tableMeta.definedColumn, + modifiedColumns: [] as typeof columns, + }, + ); + + if (columnsDiff.modifiedColumns.length) { + throw new Error( + `Column update not supported, please revert the changes for ${JSON.stringify( + columnsDiff.modifiedColumns.map(({ name }) => name), + )}`, + ); + } + + // @TODO: Handle column deletion and addition if needed + + const result = await client.updateTable(tableParam); + + logger.info(result, `Table updated successfully`); + + return { + instanceName: instanceName, + tableName: tableName, + reservedThroughput: reservedThroughput, + }; + }, + + deleteTable: async ({ + instanceName, + tableName, + }: { + instanceName: string; + tableName: string; + }) => { + const client = loadTableStore(instanceName, regionId, credentials); + const result = (await client.deleteTable({ tableName })) as { RequestId: string }; + + return { instanceName, tableName, requestId: result?.RequestId }; + }, + }; +}; diff --git a/layers/si-bootstrap-sdk/src/common/formatOtsParam.ts b/layers/si-bootstrap-sdk/src/common/formatOtsParam.ts new file mode 100644 index 0000000..5ea9dd5 --- /dev/null +++ b/layers/si-bootstrap-sdk/src/common/formatOtsParam.ts @@ -0,0 +1,42 @@ +import { DefinedColumnType } from 'tablestore'; + +const columnTypeMap = new Map([ + ['STRING', DefinedColumnType.DCT_STRING], + ['INTEGER', DefinedColumnType.DCT_INTEGER], + ['DOUBLE', DefinedColumnType.DCT_DOUBLE], + ['BOOLEAN', DefinedColumnType.DCT_BOOLEAN], +]); + +export const formatOtsTableParam = ({ + tableName, + primaryKey, + columns, + reservedThroughput, +}: { + tableName: string; + primaryKey: Array<{ name: string; type: 'STRING' | 'INTEGER' | 'BINARY' }>; + columns: Array<{ + name: string; + type: 'STRING' | 'INTEGER' | 'DOUBLE' | 'BOOLEAN' | 'BINARY'; + }>; + reservedThroughput: { + read: number; + write: number; + }; +}) => ({ + tableOptions: { + timeToLive: -1, // 永不过期 + maxVersions: 1, // 只保留最新版本 + }, + tableMeta: { + tableName: tableName, + primaryKey: primaryKey, + definedColumn: columns.map((col) => ({ + name: col.name, + type: columnTypeMap.get(col.type) as typeof DefinedColumnType.DCT_BOOLEAN, + })), + }, + reservedThroughput: { + capacityUnit: reservedThroughput, + }, +}); diff --git a/layers/si-bootstrap-sdk/src/common/index.ts b/layers/si-bootstrap-sdk/src/common/index.ts new file mode 100644 index 0000000..923660b --- /dev/null +++ b/layers/si-bootstrap-sdk/src/common/index.ts @@ -0,0 +1,2 @@ +export * from './formatOtsParam'; +export * from './logger'; diff --git a/layers/si-bootstrap-sdk/src/common/logger.ts b/layers/si-bootstrap-sdk/src/common/logger.ts new file mode 100644 index 0000000..7455ce7 --- /dev/null +++ b/layers/si-bootstrap-sdk/src/common/logger.ts @@ -0,0 +1,9 @@ +import pino from 'pino'; + +const logger = pino({ + name: 'SIBootstrapSDK', + level: ['SIBootstrapSDK', '*'].includes(process.env.DEBUG || '') ? 'debug' : 'info', + transport: { target: 'pino-pretty' }, +}); + +export { logger }; diff --git a/layers/si-bootstrap-sdk/src/index.ts b/layers/si-bootstrap-sdk/src/index.ts new file mode 100644 index 0000000..e9765b1 --- /dev/null +++ b/layers/si-bootstrap-sdk/src/index.ts @@ -0,0 +1,53 @@ +import { CustomResourceRequest, ResourceProperties, TableStoreResourceProperties } from './tyes'; +import { resources } from './resources'; +import { logger } from './common'; + +export const bootstrapHandler = async (event: CustomResourceRequest) => { + logger.info(event, 'bootstrapHandler received event'); + + const { resourceType, requestType } = event; + + const action = resources[resourceType][requestType]; + if (!action) { + logger.error( + { resourceType, requestType }, + 'Unsupported resource type or request type provided', + ); + + return { + status: 'FAILED', + reason: `Unsupported resource type or request type: ${resourceType} - ${requestType}`, + stackId: event.stackId, + logicalResourceId: event?.logicalResourceId, + physicalResourceId: event?.physicalResourceId, + }; + } + + try { + const resourceProps = + event.resourceProperties as ResourceProperties; + + const result = await action(resourceProps, event.credentials, event.regionId); + + logger.info(result, 'Action completed successfully'); + + return { + status: 'SUCCESS', + reason: 'Custom resource processed successfully.', + logicalResourceId: event?.logicalResourceId, + stackId: event.stackId, + physicalResourceId: result?.physicalResourceId || 'xxx', + data: result?.data || {}, + }; + } catch (error) { + logger.error(error, 'Error processing request'); + + return { + status: 'FAILED', + reason: error instanceof Error ? error.message : 'Internal Server Error', + logicalResourceId: event.logicalResourceId, + stackId: event.stackId, + physicalResourceId: 'xxx', + }; + } +}; diff --git a/layers/si-bootstrap-sdk/src/resources/index.ts b/layers/si-bootstrap-sdk/src/resources/index.ts new file mode 100644 index 0000000..7298ea9 --- /dev/null +++ b/layers/si-bootstrap-sdk/src/resources/index.ts @@ -0,0 +1,29 @@ +import { tableStore } from './tablestore'; +import { + Credentials, + RequestTypeEnum, + ResourceEnum, + ResourceProperties, + TableStoreResourceProperties, +} from '../tyes'; + +export const resources: { + [K in ResourceEnum]: { + [R in RequestTypeEnum]: ( + props: ResourceProperties, + credentials: Credentials, + regionId: string, + ) => Promise<{ [key: string]: unknown } | undefined>; + }; +} = { + [ResourceEnum.TABLE_STORE_C]: { + CREATE: tableStore.create, + UPDATE: tableStore.update, + DELETE: tableStore.delete, + }, + [ResourceEnum.TABLE_STORE_H]: { + CREATE: tableStore.create, + UPDATE: tableStore.update, + DELETE: tableStore.delete, + }, +}; diff --git a/layers/si-bootstrap-sdk/src/resources/tablestore.ts b/layers/si-bootstrap-sdk/src/resources/tablestore.ts new file mode 100644 index 0000000..567fe24 --- /dev/null +++ b/layers/si-bootstrap-sdk/src/resources/tablestore.ts @@ -0,0 +1,138 @@ +import { Credentials, ResourceProperties, TableStoreResourceProperties } from '../tyes'; +import { loadTableStoreClient } from '../clients'; +import { logger } from '../common'; + +const createTableStore = async ( + { + instanceName, + tableName, + primaryKey, + columns, + clusterType, + tags, + network, + reservedThroughput, + }: ResourceProperties, + credentials: Credentials, + regionId: string, +) => { + const tableStoreClient = loadTableStoreClient(regionId, credentials); + + let instance = await tableStoreClient.getInstance(instanceName); + + if (!instance) { + logger.info({ instanceName }, 'Instance does not exist, creating a new instance'); + + try { + instance = await tableStoreClient.createInstance({ + instanceName, + clusterType, + network: { + type: network.type, + vpcId: network.vpcId, + ingressRules: network.ingressRules, + }, + tags, + }); + } catch (error) { + logger.error(error, 'Failed to create instance'); + throw error; + } + } + + if (instance?.instanceStatus !== 'normal') { + throw new Error( + `Instance ${instanceName} is not in normal status, current status: ${instance?.instanceStatus}`, + ); + } + try { + const tableStore = await tableStoreClient.createTable({ + instanceName, + tableName, + primaryKey, + columns, + reservedThroughput, + }); + return { + physicalResourceId: tableStore?.tableName, + data: { + instanceName: instance.instanceName, + tableName: tableStore?.tableName, + primaryKey: tableStore?.primaryKey, + columns: tableStore?.columns, + reservedThroughput: tableStore?.reservedThroughput, + }, + }; + } catch (error) { + logger.error({ instanceName, tableName, error }, 'Failed to create table'); + throw error; + } +}; + +const updateTableStore = async ( + properties: ResourceProperties, + credentials: Credentials, + regionId: string, +) => { + const tableStoreClient = loadTableStoreClient(regionId, credentials); + + const { instanceName, tableName, reservedThroughput } = properties; + + const instance = await tableStoreClient.getInstance(instanceName); + if (!instance) { + throw new Error(`Instance ${instanceName} does not exist.`); + } + + try { + const updatedTable = await tableStoreClient.updateTable({ + instanceName, + tableName, + reservedThroughput, + }); + + return { + physicalResourceId: updatedTable.tableName, + data: { + instanceName: instance.instanceName, + tableName: updatedTable.tableName, + reservedThroughput: updatedTable.reservedThroughput, + }, + }; + } catch (error) { + logger.error({ instanceName, tableName, error }, 'Failed to update table'); + throw error; + } +}; + +const deleteTableStore = async ( + properties: ResourceProperties, + credentials: Credentials, + regionId: string, +) => { + const tableStoreClient = loadTableStoreClient(regionId, credentials); + + const { instanceName, tableName } = properties; + + const instance = await tableStoreClient.getInstance(instanceName); + if (!instance) { + throw new Error(`Instance ${instanceName} does not exist.`); + } + + try { + const result = await tableStoreClient.deleteTable({ + instanceName, + tableName, + }); + + return { physicalResourceId: tableName, data: result }; + } catch (error) { + logger.error({ instanceName, tableName, error }, 'Failed to delete table'); + throw error; + } +}; + +export const tableStore = { + create: createTableStore, + update: updateTableStore, + delete: deleteTableStore, +}; diff --git a/layers/si-bootstrap-sdk/src/tyes.ts b/layers/si-bootstrap-sdk/src/tyes.ts new file mode 100644 index 0000000..89b66d3 --- /dev/null +++ b/layers/si-bootstrap-sdk/src/tyes.ts @@ -0,0 +1,55 @@ +export enum ResourceEnum { + TABLE_STORE_C = 'TABLE_STORE_C', + TABLE_STORE_H = 'TABLE_STORE_H', +} + +export enum RequestTypeEnum { + CREATE = 'CREATE', + UPDATE = 'UPDATE', + DELETE = 'DELETE', +} + +export type ResourceProperties = { + tags?: { key: string; value: string }[]; +} & T; +export type Credentials = { + accessKeyId: string; + accessKeySecret: string; + securityToken?: string; +}; + +export type CustomResourceRequest = { + stackId: string; + stackName: string; + resourceOwnerId: string; + callerId: string; + resourceProperties: ResourceProperties; + eventType: string; + requestType: RequestTypeEnum; + resourceType: ResourceEnum; + logicalResourceId: string; + physicalResourceId?: string; + regionId: string; + requestId: string; + credentials: Credentials; +}; + +export type TableStoreResourceProperties = { + instanceName: string; + tableName: string; + primaryKey: Array<{ name: string; type: 'STRING' | 'INTEGER' | 'BINARY' }>; + columns: Array<{ + name: string; + type: 'STRING' | 'INTEGER' | 'DOUBLE' | 'BOOLEAN' | 'BINARY'; + }>; + clusterType: string; + network: { + type: 'PRIVATE' | 'PUBLIC'; + vpcId?: string; + ingressRules: Array; + }; + reservedThroughput: { + read: number; + write: number; + }; +}; diff --git a/layers/si-bootstrap-sdk/tsconfig.json b/layers/si-bootstrap-sdk/tsconfig.json new file mode 100644 index 0000000..1d8b7f6 --- /dev/null +++ b/layers/si-bootstrap-sdk/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "declaration": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "outDir": "./dist", + "rootDir": "./", + "resolveJsonModule": true, + "incremental": false, + "composite": false, + }, + "include": ["src/**/*"] +} + diff --git a/package-lock.json b/package-lock.json index ab338b5..87b70b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,10 @@ "@alicloud/ros-cdk-nas": "^1.8.0", "@alicloud/ros-cdk-oss": "^1.8.0", "@alicloud/ros-cdk-ossdeployment": "^1.8.0", + "@alicloud/ros-cdk-ots": "^1.8.0", "@alicloud/ros-cdk-ram": "^1.8.0", "@alicloud/ros-cdk-rds": "^1.8.0", + "@alicloud/ros-cdk-ros": "^1.8.0", "@alicloud/ros-cdk-sls": "^1.8.0", "@alicloud/ros-cdk-vpc": "^1.8.0", "@alicloud/ros20190910": "^3.5.6", @@ -2221,6 +2223,20 @@ "node": ">=0.4" } }, + "node_modules/@alicloud/ros-cdk-ots": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ots/-/ros-cdk-ots-1.8.0.tgz", + "integrity": "sha512-DWxw1Q7eojXJybnd+Imp/wjFzLyhScWYkS0x1Tcot4GrYcd9+nRewoyT0RtgzDNtpEBCC1JUKbeyrsYsHYzxVg==", + "license": "Apache-2.0", + "dependencies": { + "@alicloud/ros-cdk-core": "^1.7.0", + "constructs": "^3.0.4" + }, + "peerDependencies": { + "@alicloud/ros-cdk-core": "^1.7.0", + "constructs": "^3.0.4" + } + }, "node_modules/@alicloud/ros-cdk-ram": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ram/-/ros-cdk-ram-1.8.0.tgz", @@ -2250,15 +2266,16 @@ } }, "node_modules/@alicloud/ros-cdk-ros": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ros/-/ros-cdk-ros-1.4.0.tgz", - "integrity": "sha512-52AmMtKvWzf/a9IZ1ly2FcYKApW7owwk+CwLHd5c9/eDdnyor3rIg4m7i//0n5VZj9vrVY6E4hmSDid6XJfIoA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ros/-/ros-cdk-ros-1.8.0.tgz", + "integrity": "sha512-OY8e8EiQWmPn4Aig0QLce5dk+ctxopdQkQxmHjrDsNx8G5RP49hnTKeVhyv6BYcefWbPWlrbPGHiLrTXLMKEfg==", + "license": "Apache-2.0", "dependencies": { - "@alicloud/ros-cdk-core": "^1.0.27", + "@alicloud/ros-cdk-core": "^1.7.0", "constructs": "^3.0.4" }, "peerDependencies": { - "@alicloud/ros-cdk-core": "^1.0.27", + "@alicloud/ros-cdk-core": "^1.7.0", "constructs": "^3.0.4" } }, @@ -7669,6 +7686,11 @@ "node": ">=18.0.0" } }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "inBundle": true, + "license": "ISC" + }, "node_modules/npm/node_modules/@npmcli/agent": { "version": "3.0.0", "inBundle": true, @@ -7684,6 +7706,71 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "9.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^9.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^8.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^21.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "ssri": "^12.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^4.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "10.2.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "ci-info": "^4.0.0", + "ini": "^5.0.0", + "nopt": "^8.1.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "walk-up-path": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/npm/node_modules/@npmcli/fs": { "version": "4.0.0", "inBundle": true, @@ -7713,6 +7800,58 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "4.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^21.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/@npmcli/node-gyp": { "version": "4.0.0", "inBundle": true, @@ -7749,6 +7888,17 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.1.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/@npmcli/redact": { "version": "3.1.1", "inBundle": true, @@ -7758,7 +7908,7 @@ } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "9.0.2", + "version": "9.1.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -7920,6 +8070,32 @@ "inBundle": true, "license": "MIT" }, + "node_modules/npm/node_modules/bin-links": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npm/node_modules/brace-expansion": { "version": "2.0.1", "inBundle": true, @@ -7959,12 +8135,11 @@ } }, "node_modules/npm/node_modules/cacache/node_modules/minizlib": { - "version": "3.0.1", + "version": "3.0.2", "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" }, "engines": { "node": ">= 18" @@ -8019,8 +8194,16 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/npm/node_modules/ci-info": { - "version": "4.1.0", + "version": "4.2.0", "funding": [ { "type": "github", @@ -8056,6 +8239,14 @@ "node": ">= 10" } }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/color-convert": { "version": "2.0.1", "inBundle": true, @@ -8072,6 +8263,11 @@ "inBundle": true, "license": "MIT" }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC" + }, "node_modules/npm/node_modules/cross-spawn": { "version": "7.0.6", "inBundle": true, @@ -8099,6 +8295,17 @@ "node": ">= 8" } }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/npm/node_modules/debug": { "version": "4.4.0", "inBundle": true, @@ -8115,6 +8322,14 @@ } } }, + "node_modules/npm/node_modules/diff": { + "version": "7.0.0", + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/npm/node_modules/eastasianwidth": { "version": "0.2.0", "inBundle": true, @@ -8262,6 +8477,17 @@ "node": ">=0.10.0" } }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/imurmurhash": { "version": "0.1.4", "inBundle": true, @@ -8369,6 +8595,14 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/npm/node_modules/jsonparse": { "version": "1.3.1", "engines": [ @@ -8377,6 +8611,16 @@ "inBundle": true, "license": "MIT" }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "inBundle": true, + "license": "MIT" + }, "node_modules/npm/node_modules/libnpmaccess": { "version": "10.0.0", "inBundle": true, @@ -8389,6 +8633,56 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "8.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.0.2", + "@npmcli/installed-package-contents": "^3.0.0", + "binary-extensions": "^3.0.0", + "diff": "^7.0.0", + "minimatch": "^9.0.4", + "npm-package-arg": "^12.0.0", + "pacote": "^21.0.0", + "tar": "^6.2.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "10.1.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.0.2", + "@npmcli/package-json": "^6.1.1", + "@npmcli/run-script": "^9.0.1", + "ci-info": "^4.0.0", + "npm-package-arg": "^12.0.0", + "pacote": "^21.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "walk-up-path": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "7.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.0.2" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/npm/node_modules/libnpmorg": { "version": "8.0.0", "inBundle": true, @@ -8401,6 +8695,20 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "9.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.0.2", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^21.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/npm/node_modules/libnpmpublish": { "version": "11.0.0", "inBundle": true, @@ -8525,7 +8833,7 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "4.0.0", + "version": "4.0.1", "inBundle": true, "license": "MIT", "dependencies": { @@ -8541,12 +8849,11 @@ } }, "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { - "version": "3.0.1", + "version": "3.0.2", "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" }, "engines": { "node": ">= 18" @@ -8618,7 +8925,41 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/ms": { + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { "version": "2.1.3", "inBundle": true, "license": "MIT" @@ -8632,19 +8973,19 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "11.1.0", + "version": "11.2.0", "inBundle": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", + "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { @@ -8663,12 +9004,11 @@ } }, "node_modules/npm/node_modules/node-gyp/node_modules/minizlib": { - "version": "3.0.1", + "version": "3.0.2", "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" }, "engines": { "node": ">= 18" @@ -8747,6 +9087,17 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/npm-install-checks": { "version": "7.1.1", "inBundle": true, @@ -8780,6 +9131,17 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "10.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/npm/node_modules/npm-pick-manifest": { "version": "10.0.0", "inBundle": true, @@ -8825,12 +9187,11 @@ } }, "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { - "version": "3.0.1", + "version": "3.0.2", "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" }, "engines": { "node": ">= 18" @@ -8860,6 +9221,49 @@ "inBundle": true, "license": "BlueOak-1.0.0" }, + "node_modules/npm/node_modules/pacote": { + "version": "21.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^10.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/path-key": { "version": "3.1.1", "inBundle": true, @@ -8883,6 +9287,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/npm/node_modules/proc-log": { "version": "5.0.0", "inBundle": true, @@ -8891,6 +9307,30 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/proggy": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.2", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", "inBundle": true, @@ -8932,26 +9372,32 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "5.0.0", "inBundle": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">= 4" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/rimraf": { - "version": "5.0.10", + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "4.0.0", "inBundle": true, "license": "ISC", "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/npm/node_modules/safer-buffer": { @@ -9166,6 +9612,52 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/npm/node_modules/tar": { + "version": "6.2.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, "node_modules/npm/node_modules/text-table": { "version": "0.2.0", "inBundle": true, @@ -9176,6 +9668,53 @@ "inBundle": true, "license": "MIT" }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.12", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.3", + "inBundle": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm/node_modules/tuf-js": { "version": "3.0.1", "inBundle": true, @@ -9211,6 +9750,11 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, "node_modules/npm/node_modules/validate-npm-package-license": { "version": "3.0.4", "inBundle": true, @@ -9237,6 +9781,14 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/npm/node_modules/which": { "version": "5.0.0", "inBundle": true, @@ -9352,6 +9904,18 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/yallist": { "version": "4.0.0", "inBundle": true, @@ -12389,6 +12953,15 @@ } } }, + "@alicloud/ros-cdk-ots": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ots/-/ros-cdk-ots-1.8.0.tgz", + "integrity": "sha512-DWxw1Q7eojXJybnd+Imp/wjFzLyhScWYkS0x1Tcot4GrYcd9+nRewoyT0RtgzDNtpEBCC1JUKbeyrsYsHYzxVg==", + "requires": { + "@alicloud/ros-cdk-core": "^1.7.0", + "constructs": "^3.0.4" + } + }, "@alicloud/ros-cdk-ram": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ram/-/ros-cdk-ram-1.8.0.tgz", @@ -12408,11 +12981,11 @@ } }, "@alicloud/ros-cdk-ros": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ros/-/ros-cdk-ros-1.4.0.tgz", - "integrity": "sha512-52AmMtKvWzf/a9IZ1ly2FcYKApW7owwk+CwLHd5c9/eDdnyor3rIg4m7i//0n5VZj9vrVY6E4hmSDid6XJfIoA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/ros-cdk-ros/-/ros-cdk-ros-1.8.0.tgz", + "integrity": "sha512-OY8e8EiQWmPn4Aig0QLce5dk+ctxopdQkQxmHjrDsNx8G5RP49hnTKeVhyv6BYcefWbPWlrbPGHiLrTXLMKEfg==", "requires": { - "@alicloud/ros-cdk-core": "^1.0.27", + "@alicloud/ros-cdk-core": "^1.7.0", "constructs": "^3.0.4" } }, @@ -16394,6 +16967,10 @@ "minipass": "^7.0.4" } }, + "@isaacs/string-locale-compare": { + "version": "1.1.0", + "bundled": true + }, "@npmcli/agent": { "version": "3.0.0", "bundled": true, @@ -16405,6 +16982,60 @@ "socks-proxy-agent": "^8.0.3" } }, + "@npmcli/arborist": { + "version": "9.0.2", + "bundled": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^9.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^8.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^21.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "ssri": "^12.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^4.0.0" + } + }, + "@npmcli/config": { + "version": "10.2.0", + "bundled": true, + "requires": { + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "ci-info": "^4.0.0", + "ini": "^5.0.0", + "nopt": "^8.1.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "walk-up-path": "^4.0.0" + } + }, "@npmcli/fs": { "version": "4.0.0", "bundled": true, @@ -16426,6 +17057,39 @@ "which": "^5.0.0" } }, + "@npmcli/installed-package-contents": { + "version": "3.0.0", + "bundled": true, + "requires": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + } + }, + "@npmcli/map-workspaces": { + "version": "4.0.2", + "bundled": true, + "requires": { + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0" + } + }, + "@npmcli/metavuln-calculator": { + "version": "9.0.0", + "bundled": true, + "requires": { + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^21.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5" + } + }, + "@npmcli/name-from-folder": { + "version": "3.0.0", + "bundled": true + }, "@npmcli/node-gyp": { "version": "4.0.0", "bundled": true @@ -16450,12 +17114,19 @@ "which": "^5.0.0" } }, + "@npmcli/query": { + "version": "4.0.0", + "bundled": true, + "requires": { + "postcss-selector-parser": "^6.1.2" + } + }, "@npmcli/redact": { "version": "3.1.1", "bundled": true }, "@npmcli/run-script": { - "version": "9.0.2", + "version": "9.1.0", "bundled": true, "requires": { "@npmcli/node-gyp": "^4.0.0", @@ -16555,6 +17226,21 @@ "version": "1.0.2", "bundled": true }, + "bin-links": { + "version": "5.0.0", + "bundled": true, + "requires": { + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" + } + }, + "binary-extensions": { + "version": "3.0.0", + "bundled": true + }, "brace-expansion": { "version": "2.0.1", "bundled": true, @@ -16585,11 +17271,10 @@ "bundled": true }, "minizlib": { - "version": "3.0.1", + "version": "3.0.2", "bundled": true, "requires": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" } }, "mkdirp": { @@ -16618,8 +17303,12 @@ "version": "5.4.1", "bundled": true }, + "chownr": { + "version": "2.0.0", + "bundled": true + }, "ci-info": { - "version": "4.1.0", + "version": "4.2.0", "bundled": true }, "cidr-regex": { @@ -16637,6 +17326,10 @@ "strip-ansi": "^6.0.1" } }, + "cmd-shim": { + "version": "7.0.0", + "bundled": true + }, "color-convert": { "version": "2.0.1", "bundled": true, @@ -16648,6 +17341,10 @@ "version": "1.1.4", "bundled": true }, + "common-ancestor-path": { + "version": "1.0.1", + "bundled": true + }, "cross-spawn": { "version": "7.0.6", "bundled": true, @@ -16666,6 +17363,10 @@ } } }, + "cssesc": { + "version": "3.0.0", + "bundled": true + }, "debug": { "version": "4.4.0", "bundled": true, @@ -16673,6 +17374,10 @@ "ms": "^2.1.3" } }, + "diff": { + "version": "7.0.0", + "bundled": true + }, "eastasianwidth": { "version": "0.2.0", "bundled": true @@ -16771,6 +17476,13 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ignore-walk": { + "version": "7.0.0", + "bundled": true, + "requires": { + "minimatch": "^9.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "bundled": true @@ -16835,10 +17547,22 @@ "version": "4.0.0", "bundled": true }, + "json-stringify-nice": { + "version": "1.1.4", + "bundled": true + }, "jsonparse": { "version": "1.3.1", "bundled": true }, + "just-diff": { + "version": "6.0.2", + "bundled": true + }, + "just-diff-apply": { + "version": "5.5.0", + "bundled": true + }, "libnpmaccess": { "version": "10.0.0", "bundled": true, @@ -16847,6 +17571,44 @@ "npm-registry-fetch": "^18.0.1" } }, + "libnpmdiff": { + "version": "8.0.2", + "bundled": true, + "requires": { + "@npmcli/arborist": "^9.0.2", + "@npmcli/installed-package-contents": "^3.0.0", + "binary-extensions": "^3.0.0", + "diff": "^7.0.0", + "minimatch": "^9.0.4", + "npm-package-arg": "^12.0.0", + "pacote": "^21.0.0", + "tar": "^6.2.1" + } + }, + "libnpmexec": { + "version": "10.1.1", + "bundled": true, + "requires": { + "@npmcli/arborist": "^9.0.2", + "@npmcli/package-json": "^6.1.1", + "@npmcli/run-script": "^9.0.1", + "ci-info": "^4.0.0", + "npm-package-arg": "^12.0.0", + "pacote": "^21.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "walk-up-path": "^4.0.0" + } + }, + "libnpmfund": { + "version": "7.0.2", + "bundled": true, + "requires": { + "@npmcli/arborist": "^9.0.2" + } + }, "libnpmorg": { "version": "8.0.0", "bundled": true, @@ -16855,6 +17617,16 @@ "npm-registry-fetch": "^18.0.1" } }, + "libnpmpack": { + "version": "9.0.2", + "bundled": true, + "requires": { + "@npmcli/arborist": "^9.0.2", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^21.0.0" + } + }, "libnpmpublish": { "version": "11.0.0", "bundled": true, @@ -16941,7 +17713,7 @@ } }, "minipass-fetch": { - "version": "4.0.0", + "version": "4.0.1", "bundled": true, "requires": { "encoding": "^0.1.13", @@ -16951,11 +17723,10 @@ }, "dependencies": { "minizlib": { - "version": "3.0.1", + "version": "3.0.2", "bundled": true, "requires": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" } } } @@ -17008,6 +17779,27 @@ } } }, + "minizlib": { + "version": "2.1.2", + "bundled": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "mkdirp": { + "version": "1.0.4", + "bundled": true + }, "ms": { "version": "2.1.3", "bundled": true @@ -17017,18 +17809,18 @@ "bundled": true }, "node-gyp": { - "version": "11.1.0", + "version": "11.2.0", "bundled": true, "requires": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", + "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "dependencies": { @@ -17037,11 +17829,10 @@ "bundled": true }, "minizlib": { - "version": "3.0.1", + "version": "3.0.2", "bundled": true, "requires": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" } }, "mkdirp": { @@ -17086,6 +17877,13 @@ "version": "6.0.0", "bundled": true }, + "npm-bundled": { + "version": "4.0.0", + "bundled": true, + "requires": { + "npm-normalize-package-bin": "^4.0.0" + } + }, "npm-install-checks": { "version": "7.1.1", "bundled": true, @@ -17107,6 +17905,13 @@ "validate-npm-package-name": "^6.0.0" } }, + "npm-packlist": { + "version": "10.0.0", + "bundled": true, + "requires": { + "ignore-walk": "^7.0.0" + } + }, "npm-pick-manifest": { "version": "10.0.0", "bundled": true, @@ -17140,11 +17945,10 @@ }, "dependencies": { "minizlib": { - "version": "3.0.1", + "version": "3.0.2", "bundled": true, "requires": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" + "minipass": "^7.1.2" } } } @@ -17161,6 +17965,38 @@ "version": "1.0.1", "bundled": true }, + "pacote": { + "version": "21.0.0", + "bundled": true, + "requires": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^10.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + } + }, + "parse-conflict-json": { + "version": "4.0.0", + "bundled": true, + "requires": { + "json-parse-even-better-errors": "^4.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + } + }, "path-key": { "version": "3.1.1", "bundled": true @@ -17173,10 +18009,30 @@ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, + "postcss-selector-parser": { + "version": "6.1.2", + "bundled": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, "proc-log": { "version": "5.0.0", "bundled": true }, + "proggy": { + "version": "3.0.0", + "bundled": true + }, + "promise-all-reject-late": { + "version": "1.0.1", + "bundled": true + }, + "promise-call-limit": { + "version": "3.0.2", + "bundled": true + }, "promise-retry": { "version": "2.0.1", "bundled": true, @@ -17203,17 +18059,22 @@ "mute-stream": "^2.0.0" } }, - "retry": { - "version": "0.12.0", + "read-cmd-shim": { + "version": "5.0.0", "bundled": true }, - "rimraf": { - "version": "5.0.10", + "read-package-json-fast": { + "version": "4.0.0", "bundled": true, "requires": { - "glob": "^10.3.7" + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" } }, + "retry": { + "version": "0.12.0", + "bundled": true + }, "safer-buffer": { "version": "2.1.2", "bundled": true, @@ -17352,6 +18213,40 @@ "version": "10.0.0", "bundled": true }, + "tar": { + "version": "6.2.1", + "bundled": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "fs-minipass": { + "version": "2.1.0", + "bundled": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass": { + "version": "5.0.0", + "bundled": true + } + } + }, "text-table": { "version": "0.2.0", "bundled": true @@ -17360,6 +18255,29 @@ "version": "1.3.0", "bundled": true }, + "tinyglobby": { + "version": "0.2.12", + "bundled": true, + "requires": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "dependencies": { + "fdir": { + "version": "6.4.3", + "bundled": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.2", + "bundled": true + } + } + }, + "treeverse": { + "version": "3.0.0", + "bundled": true + }, "tuf-js": { "version": "3.0.1", "bundled": true, @@ -17383,6 +18301,10 @@ "imurmurhash": "^0.1.4" } }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, "validate-npm-package-license": { "version": "3.0.4", "bundled": true, @@ -17405,6 +18327,10 @@ "version": "6.0.0", "bundled": true }, + "walk-up-path": { + "version": "4.0.0", + "bundled": true + }, "which": { "version": "5.0.0", "bundled": true, @@ -17471,6 +18397,14 @@ } } }, + "write-file-atomic": { + "version": "6.0.0", + "bundled": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, "yallist": { "version": "4.0.0", "bundled": true diff --git a/package.json b/package.json index 14173be..c36de51 100644 --- a/package.json +++ b/package.json @@ -60,8 +60,10 @@ "@alicloud/ros-cdk-nas": "^1.8.0", "@alicloud/ros-cdk-oss": "^1.8.0", "@alicloud/ros-cdk-ossdeployment": "^1.8.0", + "@alicloud/ros-cdk-ots": "^1.8.0", "@alicloud/ros-cdk-ram": "^1.8.0", "@alicloud/ros-cdk-rds": "^1.8.0", + "@alicloud/ros-cdk-ros": "^1.8.0", "@alicloud/ros-cdk-sls": "^1.8.0", "@alicloud/ros-cdk-vpc": "^1.8.0", "@alicloud/ros20190910": "^3.5.6", diff --git a/samples/aliyun-poc-table.yml b/samples/aliyun-poc-table.yml new file mode 100644 index 0000000..3979153 --- /dev/null +++ b/samples/aliyun-poc-table.yml @@ -0,0 +1,47 @@ +version: 0.0.1 + +provider: + name: aliyun + region: cn-hangzhou + + +service: insight-table-poc + +tags: + owner: geek-fun + +tables: + insight_poc_table: + collection: t01wdidewc0h + name: insightPocTable + type: TABLE_STORE_H + network: + type: 'PRIVATE' + vpc_id: "vpc-12345678" + ingress_rules: + - TCP:0.0.0.0/0:80 + - TCP:0.0.0.0/0:443 + throughput: + reserved: + read: 0 + write: 0 + on_demand: + read: 100 + write: 100 + key_schema: + - name: id + type: HASH + attributes: + - name: id + type: STRING + - name: name + type: STRING + - name: birthday + type: STRING + - name: weight + type: INTEGER + - name: height + type: DOUBLE + - name: active + type: BOOLEAN + diff --git a/src/commands/deploy.ts b/src/commands/deploy.ts index 7954728..ab80500 100644 --- a/src/commands/deploy.ts +++ b/src/commands/deploy.ts @@ -19,7 +19,7 @@ export const deploy = async ( const iac = parseYaml(getIacLocation(options.location)); logger.info('Yaml is valid! 🎉'); - setContext({ ...options, stackName, iacProvider: iac.provider }); + await setContext({ ...options, stackName, iacProvider: iac.provider }, true); logger.info('Deploying stack...'); await deployStack(stackName, iac); diff --git a/src/commands/destroy.ts b/src/commands/destroy.ts index 529a1cd..0498a25 100644 --- a/src/commands/destroy.ts +++ b/src/commands/destroy.ts @@ -13,7 +13,7 @@ export const destroyStack = async ( }, ) => { const iac = parseYaml(getIacLocation(options.location)); - setContext({ stackName, ...options, iacProvider: iac.provider }); + await setContext({ stackName, ...options, iacProvider: iac.provider }, true); const context = getContext(); logger.info( `Destroying stack: ${stackName}, provider: ${context.provider}, region: ${context.region}...`, diff --git a/src/commands/index.ts b/src/commands/index.ts index 875175e..cab3ba4 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,12 +1,11 @@ #! /usr/bin/env node import { Command } from 'commander'; -import { getContext, getVersion, logger, setContext } from '../common'; +import { getContext, getIamInfo, getVersion, logger, setContext } from '../common'; import { validate } from './validate'; import { deploy } from './deploy'; import { template } from './template'; import { destroyStack } from './destroy'; -import { getIamInfo } from '../common'; const program = new Command(); @@ -16,7 +15,7 @@ program .command('show') .description('show string') .action(async (options) => { - setContext({ ...options }); + await setContext({ ...options }); const context = getContext(); const result = await getIamInfo(context); console.log('result:', JSON.stringify(result)); @@ -27,9 +26,9 @@ program .description('validate serverless Iac yaml') .option('-f, --file ', 'specify the yaml file') .option('-s, --stage ', 'specify the stage') - .action((stackName, { file, stage }) => { + .action(async (stackName, { file, stage }) => { logger.debug('log command info'); - validate(stackName, { stage, location: file }); + await validate(stackName, { stage, location: file }); }); program @@ -76,8 +75,8 @@ program .option('-f, --file ', 'specify the yaml file') .option('-s, --stage ', 'specify the stage') .option('-t, --format ', 'output content type (JSON or YAML)', 'JSON') - .action((stackName, { format, file, stage }) => { - template(stackName, { format, location: file, stage }); + .action(async (stackName, { format, file, stage }) => { + await template(stackName, { format, location: file, stage }); }); program diff --git a/src/commands/template.ts b/src/commands/template.ts index 16adcd1..5847cad 100644 --- a/src/commands/template.ts +++ b/src/commands/template.ts @@ -4,14 +4,13 @@ import { generateStackTemplate } from '../stack/deploy'; import { getIacLocation, logger, setContext } from '../common'; import { parseYaml } from '../parser'; -export const template = ( +export const template = async ( stackName: string, options: { format: TemplateFormat; location: string; stage: string | undefined }, ) => { const iac = parseYaml(getIacLocation(options.location)); - setContext({ ...options, stackName, provider: iac.provider.name }); - + await setContext({ ...options, stackName, provider: iac.provider.name }, true); const { template } = generateStackTemplate(stackName, iac); if (typeof template === 'string') { logger.info(`\n${template}`); diff --git a/src/commands/validate.ts b/src/commands/validate.ts index 00c56da..6fc8b88 100644 --- a/src/commands/validate.ts +++ b/src/commands/validate.ts @@ -1,11 +1,11 @@ import { getContext, logger, setContext } from '../common'; import { parseYaml } from '../parser'; -export const validate = ( +export const validate = async ( stackName: string, options: { location: string | undefined; stage: string | undefined }, ) => { - setContext({ stackName, ...options }); + await setContext({ stackName, ...options }); const context = getContext(); parseYaml(context.iacLocation); logger.info('Yaml is valid! 🎉'); diff --git a/src/common/constants.ts b/src/common/constants.ts index dfd9af3..6d28448 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -1,2 +1,4 @@ export const CODE_ZIP_SIZE_LIMIT = 15 * 1000 * 1000; export const OSS_DEPLOYMENT_TIMEOUT = 3000; // in seconds +export const SI_BOOTSTRAP_FC_PREFIX = 'si-bootstrap-api'; +export const SI_BOOTSTRAP_BUCKET_PREFIX = 'si-bootstrap-artifacts'; diff --git a/src/common/context.ts b/src/common/context.ts index 6b36975..3a05909 100644 --- a/src/common/context.ts +++ b/src/common/context.ts @@ -2,6 +2,7 @@ import { Context, ServerlessIac } from '../types'; import path from 'node:path'; import { ProviderEnum } from './providerEnum'; import { AsyncLocalStorage } from 'node:async_hooks'; +import { getIamInfo } from './imsClient'; const asyncLocalStorage = new AsyncLocalStorage(); @@ -15,29 +16,34 @@ export const getIacLocation = (location?: string): string => { path.resolve(projectRoot, 'serverless-insight.yml'); }; -export const setContext = (config: { - stage?: string; - stackName?: string; - region?: string; - provider?: string; - accessKeyId?: string; - accessKeySecret?: string; - securityToken?: string; - location?: string; - parameters?: { [key: string]: string }; - iacProvider?: ServerlessIac['provider']; - stages?: ServerlessIac['stages']; -}): void => { +export const setContext = async ( + config: { + stage?: string; + stackName?: string; + region?: string; + provider?: string; + accessKeyId?: string; + accessKeySecret?: string; + securityToken?: string; + location?: string; + parameters?: { [key: string]: string }; + iacProvider?: ServerlessIac['provider']; + stages?: ServerlessIac['stages']; + }, + reaValToken = false, +): Promise => { + const region = + config.region ?? + config.iacProvider?.region ?? + process.env.ROS_REGION_ID ?? + process.env.ALIYUN_REGION ?? + 'cn-hangzhou'; + const context: Context = { stage: config.stage ?? 'default', stackName: config.stackName ?? '', provider: (config.provider ?? config.iacProvider?.name ?? ProviderEnum.ALIYUN) as ProviderEnum, - region: - config.region ?? - config.iacProvider?.region ?? - process.env.ROS_REGION_ID ?? - process.env.ALIYUN_REGION ?? - 'cn-hangzhou', + region, accessKeyId: config.accessKeyId ?? (process.env.ALIYUN_ACCESS_KEY_ID as string), accessKeySecret: config.accessKeySecret ?? (process.env.ALIYUN_ACCESS_KEY_SECRET as string), securityToken: config.securityToken ?? process.env.ALIYUN_SECURITY_TOKEN, @@ -52,6 +58,11 @@ export const setContext = (config: { ), }; + if (reaValToken) { + const iamInfo = await getIamInfo(context); + context.accountId = iamInfo?.accountId; + } + asyncLocalStorage.enterWith(context); }; diff --git a/src/common/imsClient.ts b/src/common/imsClient.ts index 69413ce..adfb015 100644 --- a/src/common/imsClient.ts +++ b/src/common/imsClient.ts @@ -12,6 +12,7 @@ export const getIamInfo = async (context: Context) => { const { body } = await imsClient.getUser( new ims20190815.GetUserRequest({ userAccessKeyId: context.accessKeyId }), ); + return body?.user ? { ...body.user, diff --git a/src/parser/index.ts b/src/parser/index.ts index d8ad38a..c6e3ac1 100644 --- a/src/parser/index.ts +++ b/src/parser/index.ts @@ -7,6 +7,7 @@ import { parseTag } from './tagParser'; import { parse } from 'yaml'; import { validateYaml } from '../validator'; import { parseBucket } from './bucketParser'; +import { parseTable } from './tableParser'; const validateExistence = (path: string) => { if (!existsSync(path)) { @@ -24,6 +25,7 @@ const transformYaml = (iacJson: ServerlessIacRaw): ServerlessIac => { functions: parseFunction(iacJson.functions), events: parseEvent(iacJson.events), databases: parseDatabase(iacJson.databases), + tables: parseTable(iacJson.tables), tags: parseTag(iacJson.tags), buckets: parseBucket(iacJson.buckets), }; diff --git a/src/parser/tableParser.ts b/src/parser/tableParser.ts new file mode 100644 index 0000000..5d32a75 --- /dev/null +++ b/src/parser/tableParser.ts @@ -0,0 +1,55 @@ +import { AttributeTypeEnum, KeyTypeEnum, TableDomain, TableRaw } from '../types/domains/table'; +import { isEmpty, omitBy, isNil } from 'lodash'; + +export function parseTable(tablesRaw?: { + [key: string]: TableRaw; +}): Array | undefined { + if (isEmpty(tablesRaw)) { + return undefined; + } + + return Object.entries(tablesRaw)?.map(([key, table]) => { + const throughput = omitBy( + { + reserved: omitBy( + { + read: table.throughput?.reserved?.read, + write: table.throughput?.reserved?.write, + }, + isNil, + ), + onDemand: omitBy( + { + read: table.throughput?.on_demand?.read, + write: table.throughput?.on_demand?.write, + }, + isNil, + ), + }, + isEmpty, + ); + + return { + key, + collection: table.collection, + name: table.name, + type: table.type, + desc: table.desc, + network: { + type: table.network?.type ?? 'PRIVATE', + ingressRules: table.network?.ingress_rules ?? [], + }, + throughput: !isEmpty(throughput) ? throughput : undefined, + keySchema: + table.key_schema?.map((keySchema) => ({ + name: keySchema.name, + type: keySchema.type as KeyTypeEnum, + })) ?? [], + attributes: + table.attributes?.map((attribute) => ({ + name: attribute.name, + type: attribute.type as AttributeTypeEnum, + })) ?? [], + }; + }); +} diff --git a/src/stack/rosStack/bootstrap.ts b/src/stack/rosStack/bootstrap.ts index 5e0ca70..e6fcc32 100644 --- a/src/stack/rosStack/bootstrap.ts +++ b/src/stack/rosStack/bootstrap.ts @@ -1,9 +1,13 @@ -import { getContext, getIamInfo, rosStackDeploy } from '../../common'; +import { + getContext, + rosStackDeploy, + SI_BOOTSTRAP_BUCKET_PREFIX, + SI_BOOTSTRAP_FC_PREFIX, +} from '../../common'; import { Context } from '../../types'; const getBootstrapTemplate = async (context: Context) => { - const iamInfo = await getIamInfo(context); - const stackName = `si-bootstrap-${iamInfo?.accountId}-${context.region}`; + const stackName = `si-bootstrap-${context.accountId}-${context.region}`; const template = { Description: 'ServerlessInsight Bootstrap Stack', @@ -17,9 +21,7 @@ const getBootstrapTemplate = async (context: Context) => { si_auto_artifacts_bucket: { Type: 'ALIYUN::OSS::Bucket', Properties: { - BucketName: { - 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', - }, + BucketName: `${SI_BOOTSTRAP_BUCKET_PREFIX}-${context.accountId}-${context.region}`, AccessControl: 'private', DeletionForce: false, EnableOssHdfsService: false, @@ -29,8 +31,158 @@ const getBootstrapTemplate = async (context: Context) => { }, }, }, + si_auto_bootstrap_api_lambda: { + Type: 'ALIYUN::FC3::Function', + Properties: { + FunctionName: `${SI_BOOTSTRAP_FC_PREFIX}-${context.accountId}-${context.region}`, + Description: 'ServerlessInsight Bootstrap API', + Handler: 'index.handler', + Runtime: 'nodejs20', + Layers: ['acs:fc:cn-hangzhou:1990893136649406:layers/si-bootstrap-sdk/versions/9'], + Code: { + SourceCode: ` +const { bootstrapHandler } = require('@geek-fun/si-bootstrap-sdk'); + +module.exports.handler = async (rawEvent, context) => { + // 处理 Buffer 类型的事件 + const event = parseEvent(rawEvent); + + const commonResponse = { + RequestId: event.requestId, + LogicalResourceId: event.logicalResourceId, + StackId: event.stackId + }; + + try { + // 处理业务逻辑 + const result = await bootstrapHandler(event); + + // 构建符合 ROS 要求的响应结构 + const rosResponse = { + ...commonResponse, + Status: result.status, + Reason: result.reason, + PhysicalResourceId: result.physicalResourceId, + Data: result.data || {} // 业务数据 + }; + + // 如果是删除操作,不需要返回数据 + if (event.requestType === 'Delete') { + delete rosResponse.Data; + } + + // 发送响应到 ROS 服务(如果提供了 ResponseURL) + if (event.responseURL) { + await sendResponse(event.responseURL, rosResponse); + } + + // 返回成功响应 + return { + statusCode: 200, + body: JSON.stringify({ + message: 'Request processed successfully', + rosResponse + }) + }; + } catch (error) { + console.error('Error:', error); + + // 构建错误响应 + const errorResponse = { + ...commonResponse, + Status: 'FAILED', + Reason: error.message || 'Internal Server Error', + PhysicalResourceId: 'error-' + Date.now() + }; + + // 发送错误响应到 ROS 服务 + if (event.responseURL) { + try { + await sendResponse(event.responseURL, errorResponse); + } catch (err) { + console.error('Failed to send error response:', err); + } + } + + // 返回错误响应 + return { + statusCode: 500, + body: JSON.stringify({ + error: 'Internal Server Error', + details: error.message, + rosErrorResponse: errorResponse + }) + }; + } +}; + +// 使用原生 fetch API 发送响应 +async function sendResponse(responseUrl, responseBody) { + + try { + const body = JSON.stringify(responseBody); + + const response = await fetch(responseUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(body).toString(), + 'Date': new Date().toUTCString() + }, + body: body + }); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(\`Failed to send response. Status: \${response.status}, Body: \${errorText}\`); + } + + console.log('Response sent successfully'); + } catch (error) { + console.error('Error sending response:', error); + throw error; + } +} + + +const parseEvent = (rawEvent) => { +// 处理 Buffer 类型的事件 + let event; + if (Buffer.isBuffer(rawEvent)) { + event = JSON.parse(rawEvent.toString('utf8')); + } else if (typeof rawEvent === 'string') { + event = JSON.parse(rawEvent); + } else { + event = rawEvent; + } + + const { credentials, ...resourceProperties } = event.ResourceProperties + return { + stackId: event.StackId, + responseURL: event.ResponseURL, + resourceOwnerId: event.ResourceOwnerId, + callerId: event.CallerId, + resourceProperties, + eventType: event.ResourceType, + requestType: event.RequestType?.toUpperCase(), + resourceType: resourceProperties.resource, + regionId: event.RegionId, + stackName: event.StackName, + requestId: event.RequestId, + intranetResponseURL: event.IntranetResponseURL, + logicalResourceId: event.LogicalResourceId, + physicalResourceId: event.PhysicalResourceId, + credentials + }; +};`, + }, + MemorySize: 512, + Timeout: 900, // 15 minutes + }, + }, }, }; + return { stackName, template }; }; diff --git a/src/stack/rosStack/function.ts b/src/stack/rosStack/function.ts index be0355e..f38c3bf 100644 --- a/src/stack/rosStack/function.ts +++ b/src/stack/rosStack/function.ts @@ -14,6 +14,7 @@ import { OSS_DEPLOYMENT_TIMEOUT, readCodeSize, resolveCode, + SI_BOOTSTRAP_BUCKET_PREFIX, } from '../../common'; import * as fc from '@alicloud/ros-cdk-fc3'; import { isEmpty } from 'lodash'; @@ -139,9 +140,7 @@ export const resolveFunctions = ( return { fcName, ...getFileSource(fcName, code!.path) }; }); - const destinationBucketName = ros.Fn.sub( - 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', - ); + const destinationBucketName = `${SI_BOOTSTRAP_BUCKET_PREFIX}-${context.accountId}-${context.region}`; const ossDeploymentId = 'si_auto_artifacts_code_deployment'; if (!isEmpty(fileSources)) { diff --git a/src/stack/rosStack/index.ts b/src/stack/rosStack/index.ts index b832e6a..481a3b1 100644 --- a/src/stack/rosStack/index.ts +++ b/src/stack/rosStack/index.ts @@ -8,6 +8,7 @@ import { resolveVars } from './vars'; import { resolveDatabases } from './database'; import { resolveEvents } from './event'; import { resolveBuckets } from './bucket'; +import { resolveTables } from './table'; export * from './bootstrap'; @@ -33,6 +34,8 @@ export class RosStack extends ros.Stack { resolveEvents(this, iac.events, iac.tags, context, this.service); // Define Databases resolveDatabases(this, iac.databases, context); + // Define Tables + resolveTables(this, iac.tables, iac.tags, context); // Define Buckets resolveBuckets(this, iac.buckets, context); } diff --git a/src/stack/rosStack/table.ts b/src/stack/rosStack/table.ts new file mode 100644 index 0000000..1373978 --- /dev/null +++ b/src/stack/rosStack/table.ts @@ -0,0 +1,82 @@ +import * as ros from '@alicloud/ros-cdk-core'; +import * as rosRos from '@alicloud/ros-cdk-ros'; + +import { Context, ServerlessIac } from '../../types'; +import { isEmpty } from 'lodash'; +import { TableDomain, TableEnum } from '../../types/domains/table'; +import { calcRefs, SI_BOOTSTRAP_FC_PREFIX } from '../../common'; + +const tableEngineMap = new Map([ + [ + TableEnum.TABLE_STORE_C, + { + clusterType: 'HYBRID', + }, + ], + [ + TableEnum.TABLE_STORE_H, + { + clusterType: 'SSD', + }, + ], +]); + +export const resolveTables = ( + scope: ros.Construct, + tables: Array | undefined, + tags: ServerlessIac['tags'] | undefined, + context: Context, +) => { + if (isEmpty(tables)) { + return undefined; + } + + tables!.forEach((tableDomain) => { + const { collection, throughput, attributes, keySchema, network } = tableDomain; + + const primaryKey = keySchema.map((key) => { + const name = calcRefs(key.name, context); + const type = + attributes.find((attribute) => calcRefs(attribute.name, context) === name)?.type || + 'STRING'; + + return { name, type: calcRefs(type, context) }; + }); + + const columns = + attributes + ?.filter(({ name }) => !primaryKey.find((pk) => pk.name === calcRefs(name, context))) + .map((attribute) => ({ + name: calcRefs(attribute.name, context), + type: calcRefs(attribute.type, context), + })) || []; + + const clusterType = tableEngineMap.get(calcRefs(tableDomain.type, context))?.clusterType; + + new rosRos.RosCustomResource( + scope, + tableDomain.key, + { + serviceToken: `acs:fc:${context.region}:${context.accountId}:functions/${SI_BOOTSTRAP_FC_PREFIX}-${context.accountId}-${context.region}`, + timeout: 600, + parameters: { + resource: calcRefs(tableDomain.type, context), + instanceName: calcRefs(collection, context), + tableName: calcRefs(tableDomain.name, context), + primaryKey, + columns, + clusterType, + network, + reservedThroughput: calcRefs(throughput?.reserved, context), + tags, + credentials: { + accessKeyId: context.accessKeyId, + accessKeySecret: context.accessKeySecret, + securityToken: context.securityToken, + }, + }, + }, + true, + ); + }); +}; diff --git a/src/types/domains/context.ts b/src/types/domains/context.ts index 21739c1..8f7bb77 100644 --- a/src/types/domains/context.ts +++ b/src/types/domains/context.ts @@ -2,6 +2,7 @@ import { ProviderEnum } from '../../common'; export type Context = { region: string; + accountId?: string; provider: ProviderEnum; stackName: string; stage: string; diff --git a/src/types/domains/table.ts b/src/types/domains/table.ts new file mode 100644 index 0000000..67b99c9 --- /dev/null +++ b/src/types/domains/table.ts @@ -0,0 +1,76 @@ +export const enum TableEnum { + TABLE_STORE_C = 'TABLE_STORE_C', + TABLE_STORE_H = 'TABLE_STORE_H', +} + +export type TableRaw = { + collection: string; + name: string; + type: TableEnum; + desc?: string; + network?: { + type: 'PUBLIC' | 'PRIVATE'; + ingress_rules?: Array; + }; + throughput?: { + reserved?: { + read?: string; + write?: string; + }; + on_demand?: { + read?: string; + write?: string; + }; + }; + key_schema: Array<{ + name: string; + type: string; + }>; + attributes: Array<{ + name: string; + type: string; + }>; +}; + +export enum AttributeTypeEnum { + STRING = 'STRING', // UTF-8, nullable string + INTEGER = 'INTEGER', // 64 bit signed integer, 8 bytes + DOUBLE = 'DOUBLE', // 64 bit double, 8 bytes + BOOLEAN = 'BOOLEAN', // true/false, 1 byte + BINARY = 'BINARY', // binary type +} + +export enum KeyTypeEnum { + HASH = 'HASH', // Primary key type, used for partitioning data + RANGE = 'RANGE', // Sort key type, used for sorting data within a partition +} + +export type TableDomain = { + key: string; + collection: string; + name: string; + type: TableEnum; + desc?: string; + network: { + type: 'PUBLIC' | 'PRIVATE'; + ingressRules: Array; + }; + throughput?: { + reserved?: { + read: number; + write: number; + }; + onDemand?: { + read: number; + write: number; + }; + }; + keySchema: Array<{ + name: string; + type: KeyTypeEnum; + }>; + attributes: Array<{ + name: string; + type: AttributeTypeEnum; + }>; +}; diff --git a/src/types/index.ts b/src/types/index.ts index e724ce1..de14e22 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -5,6 +5,7 @@ import { DatabaseDomain, DatabaseRaw } from './domains/database'; import { FunctionDomain, FunctionRaw } from './domains/function'; import { Provider } from './domains/provider'; import { BucketDomain, BucketRaw } from './domains/bucket'; +import { TableDomain, TableRaw } from './domains/table'; export * from './domains/database'; export * from './domains/event'; @@ -25,6 +26,7 @@ export type ServerlessIacRaw = { functions: { [key: string]: FunctionRaw }; events: { [key: string]: EventRaw }; databases: { [key: string]: DatabaseRaw }; + tables: { [key: string]: TableRaw }; buckets: { [key: string]: BucketRaw }; }; @@ -38,5 +40,6 @@ export type ServerlessIac = { functions?: Array; events?: Array; databases?: Array; + tables?: Array; buckets?: Array; }; diff --git a/src/validator/iacSchema.ts b/src/validator/iacSchema.ts index 3312d6f..7602310 100644 --- a/src/validator/iacSchema.ts +++ b/src/validator/iacSchema.ts @@ -6,6 +6,7 @@ import { databaseSchema } from './databaseSchema'; import { eventSchema } from './eventSchema'; import { functionSchema } from './functionSchema'; import { bucketSchema } from './bucketSchema'; +import { tableSchema } from './tableschema'; type IacSchemaError = { instancePath: string; @@ -39,6 +40,7 @@ const validate = ajv .addSchema(functionSchema) .addSchema(eventSchema) .addSchema(databaseSchema) + .addSchema(tableSchema) .addSchema(bucketSchema) .compile(rootSchema); diff --git a/src/validator/rootSchema.ts b/src/validator/rootSchema.ts index 6cf9a33..6fe5dc8 100644 --- a/src/validator/rootSchema.ts +++ b/src/validator/rootSchema.ts @@ -46,6 +46,9 @@ export const rootSchema = { buckets: { $ref: 'https://serverlessinsight.geekfun.club/schemas/bucketschema.json', }, + tables: { + $ref: 'https://serverlessinsight.geekfun.club/schemas/tableschema.json', + }, }, required: ['version', 'provider', 'service'], additionalProperties: false, diff --git a/src/validator/tableschema.ts b/src/validator/tableschema.ts new file mode 100644 index 0000000..62d5288 --- /dev/null +++ b/src/validator/tableschema.ts @@ -0,0 +1,69 @@ +export const tableSchema = { + $id: 'https://serverlessinsight.geekfun.club/schemas/tableschema.json', + type: 'object', + patternProperties: { + '.*': { + type: 'object', + properties: { + collection: { type: 'string' }, + name: { type: 'string' }, + type: { type: 'string', enum: ['TABLE_STORE_C', 'TABLE_STORE_H'] }, + desc: { type: 'string', maxLength: 256 }, + network: { + type: 'object', + properties: { + type: { type: 'string', enum: ['PUBLIC', 'PRIVATE'] }, + ingress_rules: { + type: 'array', + items: { type: 'string' }, + }, + }, + required: ['type'], + }, + throughput: { + type: 'object', + properties: { + reserved: { + type: 'object', + properties: { + read: { type: 'integer' }, + write: { type: 'integer' }, + }, + }, + on_demand: { + type: 'object', + properties: { + read: { type: 'integer' }, + write: { type: 'integer' }, + }, + }, + }, + }, + key_schema: { + type: 'array', + items: { + type: 'object', + properties: { + name: { type: 'string' }, + type: { type: 'string', enum: ['HASH', 'RANGE'] }, + }, + required: ['name', 'type'], + }, + }, + attributes: { + type: 'array', + items: { + type: 'object', + properties: { + name: { type: 'string' }, + type: { type: 'string', enum: ['STRING', 'INTEGER', 'DOUBLE', 'BOOLEAN', 'BINARY'] }, + }, + required: ['name', 'type'], + }, + }, + }, + required: ['collection', 'name', 'type', 'key_schema', 'attributes'], + additionalProperties: false, + }, + }, +}; diff --git a/tests/commands/deploy.test.ts b/tests/commands/deploy.test.ts index ae08a4f..0ce6561 100644 --- a/tests/commands/deploy.test.ts +++ b/tests/commands/deploy.test.ts @@ -1,6 +1,13 @@ import { deploy } from '../../src/commands/deploy'; +const mockedIamInfo = jest.fn(); const mockedDeployStack = jest.fn(); + +jest.mock('../../src/common/imsClient', () => ({ + ...jest.requireActual('../../src/common/imsClient'), + getIamInfo: (...rags: unknown[]) => mockedIamInfo(...rags), +})); + jest.mock('../../src/stack', () => ({ ...jest.requireActual('../../src/stack'), deployStack: (...args: unknown[]) => mockedDeployStack(...args), @@ -8,6 +15,8 @@ jest.mock('../../src/stack', () => ({ describe('unit test for deploy command', () => { it('should construct valid context and deploy the stack when deploy with valid iac', async () => { + mockedIamInfo.mockResolvedValue({ accountId: '123456789012', region: 'cn-hangzhou' }); + const stackName = 'my-demo-stack'; await deploy(stackName, { diff --git a/tests/commands/template.test.ts b/tests/commands/template.test.ts index 5005ff3..5b166c4 100644 --- a/tests/commands/template.test.ts +++ b/tests/commands/template.test.ts @@ -3,32 +3,56 @@ import { TemplateFormat } from '../../src/types'; import { jsonTemplate, yamlTemplate } from '../fixtures/templateFixture'; const mockedLogger = jest.fn(); +const mockedGetContext = jest.fn(); + jest.mock('../../src/common/logger', () => ({ logger: { info: (...args: unknown[]) => mockedLogger(...args), debug: jest.fn() }, })); + +jest.mock('../../src/common/imsClient', () => ({ + getIamInfo: jest.fn().mockResolvedValue({ accountId: '123456789012', region: 'cn-hangzhou' }), +})); + +jest.mock('../../src/common/context', () => ({ + ...jest.requireActual('../../src/common/context'), + getContext: (...args: unknown[]) => mockedGetContext(...args), +})); + const stackName = 'printTemplateStack'; const location = 'tests/fixtures/serverless-insight.yml'; describe('Unit test for template command', () => { beforeEach(() => { + mockedGetContext.mockReturnValue({ + accountId: '123456789012', + region: 'cn-hangzhou', + stage: 'default', + stackName, + provider: 'aliyun', + }); + }); + + afterEach(() => { mockedLogger.mockRestore(); + mockedGetContext.mockRestore(); }); - it('should print the template in JSON format by default', () => { + + it('should print the template in JSON format by default', async () => { const options = { format: TemplateFormat.JSON, location, stage: undefined, }; - template(stackName, options); + await template(stackName, options); expect(mockedLogger).toHaveBeenCalledWith(`\n${JSON.stringify(jsonTemplate, null, 2)}`); }); - it('should print the template in YAML format when specified', () => { + it('should print the template in YAML format when specified', async () => { const options = { format: TemplateFormat.YAML, location, stage: undefined }; - template(stackName, options); + await template(stackName, options); expect(mockedLogger).toHaveBeenCalledWith(yamlTemplate); }); diff --git a/tests/fixtures/deploy-fixtures/oneFcLargeCode.ts b/tests/fixtures/deploy-fixtures/oneFcLargeCode.ts index b1003e9..a476d1e 100644 --- a/tests/fixtures/deploy-fixtures/oneFcLargeCode.ts +++ b/tests/fixtures/deploy-fixtures/oneFcLargeCode.ts @@ -210,6 +210,7 @@ export const largeCodeRos = { ServiceConfig: { FunctionComputeConfig: { FcVersion: '3.0', + FcRegionId: 'cn-hangzhou', FunctionName: { 'Fn::GetAtt': ['hello_fn', 'FunctionName'], }, @@ -234,9 +235,7 @@ export const largeCodeRos = { DependsOn: ['sls_project', 'sls_logstore', 'sls_index', 'si_auto_artifacts_code_deployment'], Properties: { Code: { - OssBucketName: { - 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', - }, + OssBucketName: 'si-bootstrap-artifacts-123456789012-cn-hangzhou', OssObjectName: 'hello-fn/43cb4c356149762dbe507fc1baede172-large-artifact.zip', }, EnvironmentVariables: { @@ -262,9 +261,7 @@ export const largeCodeRos = { si_auto_artifacts_code_deployment: { Properties: { Parameters: { - destinationBucket: { - 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', - }, + destinationBucket: 'si-bootstrap-artifacts-123456789012-cn-hangzhou', retainOnCreate: false, sources: [ { diff --git a/tests/fixtures/serverless-insight-table-mini.yml b/tests/fixtures/serverless-insight-table-mini.yml new file mode 100644 index 0000000..db34a3e --- /dev/null +++ b/tests/fixtures/serverless-insight-table-mini.yml @@ -0,0 +1,23 @@ +version: 0.0.1 + +provider: + name: aliyun + region: cn-chengdu + + +service: insight-table-poc-mini + +tags: + owner: geek-fun + +tables: + insight_poc_table: + collection: store_or_instance_id + name: insight-poc-table + type: TABLE_STORE_H + key_schema: + - name: id + type: HASH + attributes: + - name: id + type: STRING diff --git a/tests/fixtures/serverless-insight-table.yml b/tests/fixtures/serverless-insight-table.yml new file mode 100644 index 0000000..3115780 --- /dev/null +++ b/tests/fixtures/serverless-insight-table.yml @@ -0,0 +1,36 @@ +version: 0.0.1 + +provider: + name: aliyun + region: cn-chengdu + + +service: insight-table-poc + +tags: + owner: geek-fun + +tables: + insight_poc_table: + collection: store_or_instance_name + name: insight-poc-table + desc: 'This is a test table for serverless insight' + type: TABLE_STORE_C + network: + type: 'PRIVATE' + ingress_rules: + - TCP:0.0.0.0/0:80 + - TCP:0.0.0.0/0:443 + throughput: + reserved: + read: 2 + write: 10 + on_demand: + read: 100 + write: 100 + key_schema: + - name: id + type: HASH + attributes: + - name: id + type: STRING diff --git a/tests/parser/parse.test.ts b/tests/parser/parse.test.ts index 4806aba..160a0f3 100644 --- a/tests/parser/parse.test.ts +++ b/tests/parser/parse.test.ts @@ -46,4 +46,66 @@ describe('unit test for parse', () => { }); }); }); + + describe('domain - tables', () => { + const iacLocation = path.resolve(__dirname, '../fixtures/serverless-insight-table.yml'); + + it('should parse tables from yaml to domain instance when the yaml is valid', () => { + const domain = parseYaml(iacLocation); + expect(domain.tables).toEqual([ + { + key: 'insight_poc_table', + collection: 'store_or_instance_name', + desc: 'This is a test table for serverless insight', + name: 'insight-poc-table', + type: 'TABLE_STORE_C', + network: { + type: 'PRIVATE', + ingressRules: ['TCP:0.0.0.0/0:80', 'TCP:0.0.0.0/0:443'], + }, + throughput: { + reserved: { + read: 2, + write: 10, + }, + onDemand: { + read: 100, + write: 100, + }, + }, + keySchema: [{ name: 'id', type: 'HASH' }], + attributes: [{ name: 'id', type: 'STRING' }], + }, + ]); + }); + + it('should set the default value when not provided by client', () => { + const iacLocation = path.resolve(__dirname, '../fixtures/serverless-insight-table-mini.yml'); + const domain = parseYaml(iacLocation); + expect(domain.tables).toEqual([ + { + key: 'insight_poc_table', + collection: 'store_or_instance_id', + name: 'insight-poc-table', + type: 'TABLE_STORE_H', + network: { + type: 'PRIVATE', + ingressRules: [], + }, + attributes: [ + { + name: 'id', + type: 'STRING', + }, + ], + keySchema: [ + { + name: 'id', + type: 'HASH', + }, + ], + }, + ]); + }); + }); }); diff --git a/tests/stack/deploy.test.ts b/tests/stack/deploy.test.ts index f66aee8..cd81a39 100644 --- a/tests/stack/deploy.test.ts +++ b/tests/stack/deploy.test.ts @@ -132,7 +132,7 @@ describe('Unit tests for stack deployment', () => { it('should create bucket and store code artifact to bucket when code size > 15MB', async () => { const stackName = 'my-large-code-stack'; - mockedGetStore.mockReturnValue({ stackName }); + mockedGetStore.mockReturnValue({ stackName, accountId: '123456789012', region: 'cn-hangzhou' }); mockedRosStackDeploy.mockResolvedValueOnce(stackName); await deployStack(