diff --git a/package-lock.json b/package-lock.json index b3465bc..4f1cb28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@aws-sdk/credential-providers": "^3.1024.0", "@smithy/shared-ini-file-loader": "^4.4.7", "@tigrisdata/iam": "^1.4.1", - "@tigrisdata/storage": "^2.15.6", + "@tigrisdata/storage": "^2.16.2", "commander": "^14.0.3", "enquirer": "^2.4.1", "jose": "^6.2.2", @@ -1416,38 +1416,35 @@ } }, "node_modules/@emnapi/core": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", - "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.1", + "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", - "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", + "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -2290,9 +2287,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.122.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", - "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", + "version": "0.123.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.123.0.tgz", + "integrity": "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==", "dev": true, "license": "MIT", "funding": { @@ -2358,9 +2355,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g==", "cpu": [ "arm64" ], @@ -2375,9 +2372,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA==", "cpu": [ "arm64" ], @@ -2392,9 +2389,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz", - "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.13.tgz", + "integrity": "sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug==", "cpu": [ "x64" ], @@ -2409,9 +2406,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz", - "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.13.tgz", + "integrity": "sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA==", "cpu": [ "x64" ], @@ -2426,9 +2423,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz", - "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.13.tgz", + "integrity": "sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw==", "cpu": [ "arm" ], @@ -2443,9 +2440,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg==", "cpu": [ "arm64" ], @@ -2460,9 +2457,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz", - "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.13.tgz", + "integrity": "sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA==", "cpu": [ "arm64" ], @@ -2477,9 +2474,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ==", "cpu": [ "ppc64" ], @@ -2494,9 +2491,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg==", "cpu": [ "s390x" ], @@ -2511,9 +2508,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA==", "cpu": [ "x64" ], @@ -2528,9 +2525,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz", - "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.13.tgz", + "integrity": "sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w==", "cpu": [ "x64" ], @@ -2545,9 +2542,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w==", "cpu": [ "arm64" ], @@ -2562,9 +2559,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz", - "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.13.tgz", + "integrity": "sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g==", "cpu": [ "wasm32" ], @@ -2572,16 +2569,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1" + "@emnapi/core": "1.9.1", + "@emnapi/runtime": "1.9.1", + "@napi-rs/wasm-runtime": "^1.1.2" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz", - "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.13.tgz", + "integrity": "sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ==", "cpu": [ "arm64" ], @@ -2596,9 +2595,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz", - "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.13.tgz", + "integrity": "sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ==", "cpu": [ "x64" ], @@ -2613,9 +2612,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz", - "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.13.tgz", + "integrity": "sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==", "dev": true, "license": "MIT" }, @@ -4016,16 +4015,16 @@ } }, "node_modules/@tigrisdata/storage": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/@tigrisdata/storage/-/storage-2.15.6.tgz", - "integrity": "sha512-DLMdiw6BLCqJ5M9gKg33MHRCYQdKhAxvpF2OSTj61/rtGOo5ZUswjOW80osLJGM4KGZIbisWQYkQ0shF52Z4AA==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@tigrisdata/storage/-/storage-2.16.2.tgz", + "integrity": "sha512-O17sUXp+8o5d+fjUwDYO4RhdRloJ3KazM+ICG7pbo682aKX5ROpnYH8zJn3qpzLn49CJy9TpdyknjuxrTX/aLA==", "license": "MIT", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", - "@aws-sdk/client-s3": "^3.1006.0", - "@aws-sdk/lib-storage": "^3.1006.0", - "@aws-sdk/s3-request-presigner": "^3.1006.0", - "@smithy/signature-v4": "^5.3.11", + "@aws-sdk/client-s3": "^3.1018.0", + "@aws-sdk/lib-storage": "^3.1018.0", + "@aws-sdk/s3-request-presigner": "^3.1018.0", + "@smithy/signature-v4": "^5.3.12", "dotenv": "^17.3.1" } }, @@ -10309,14 +10308,14 @@ } }, "node_modules/rolldown": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz", - "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.13.tgz", + "integrity": "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.122.0", - "@rolldown/pluginutils": "1.0.0-rc.12" + "@oxc-project/types": "=0.123.0", + "@rolldown/pluginutils": "1.0.0-rc.13" }, "bin": { "rolldown": "bin/cli.mjs" @@ -10325,21 +10324,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.12", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", - "@rolldown/binding-darwin-x64": "1.0.0-rc.12", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" + "@rolldown/binding-android-arm64": "1.0.0-rc.13", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.13", + "@rolldown/binding-darwin-x64": "1.0.0-rc.13", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.13", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.13", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.13", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.13", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13" } }, "node_modules/rollup": { @@ -11611,16 +11610,16 @@ } }, "node_modules/vite": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", - "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.7.tgz", + "integrity": "sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.12", + "rolldown": "1.0.0-rc.13", "tinyglobby": "^0.2.15" }, "bin": { @@ -11638,7 +11637,7 @@ "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", - "esbuild": "^0.27.0", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", diff --git a/package.json b/package.json index 2af1820..d9b0bcc 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "@aws-sdk/credential-providers": "^3.1024.0", "@smithy/shared-ini-file-loader": "^4.4.7", "@tigrisdata/iam": "^1.4.1", - "@tigrisdata/storage": "^2.15.6", + "@tigrisdata/storage": "^2.16.2", "commander": "^14.0.3", "enquirer": "^2.4.1", "jose": "^6.2.2", diff --git a/src/lib/access-keys/list.ts b/src/lib/access-keys/list.ts index d113f3b..261fa25 100644 --- a/src/lib/access-keys/list.ts +++ b/src/lib/access-keys/list.ts @@ -1,9 +1,15 @@ import { getIAMConfig } from '@auth/iam.js'; import { listAccessKeys } from '@tigrisdata/iam'; import { failWithError } from '@utils/exit.js'; -import { formatOutput } from '@utils/format.js'; -import { msg, printEmpty, printStart, printSuccess } from '@utils/messages.js'; -import { getFormat } from '@utils/options.js'; +import { formatOutput, formatPaginatedOutput } from '@utils/format.js'; +import { + msg, + printEmpty, + printPaginationHint, + printStart, + printSuccess, +} from '@utils/messages.js'; +import { getFormat, getPaginationOptions } from '@utils/options.js'; const context = msg('access-keys', 'list'); @@ -11,10 +17,15 @@ export default async function list(options: Record) { printStart(context); const format = getFormat(options); + const { limit, pageToken, isPaginated } = getPaginationOptions(options); const config = await getIAMConfig(context); - const { data, error } = await listAccessKeys({ config }); + const { data, error } = await listAccessKeys({ + ...(limit !== undefined ? { limit } : {}), + ...(pageToken ? { paginationToken: pageToken } : {}), + config, + }); if (error) { failWithError(context, error); @@ -32,13 +43,26 @@ export default async function list(options: Record) { created: key.createdAt, })); - const output = formatOutput(keys, format!, 'keys', 'key', [ + const columns = [ { key: 'name', header: 'Name' }, { key: 'id', header: 'ID' }, { key: 'status', header: 'Status' }, { key: 'created', header: 'Created' }, - ]); + ]; + + const nextToken = data.paginationToken || undefined; + + const output = isPaginated + ? formatPaginatedOutput(keys, format!, 'keys', 'key', columns, { + paginationToken: nextToken, + }) + : formatOutput(keys, format!, 'keys', 'key', columns); console.log(output); + + if (isPaginated && format !== 'json' && format !== 'xml') { + printPaginationHint(nextToken); + } + printSuccess(context, { count: keys.length }); } diff --git a/src/lib/buckets/list.ts b/src/lib/buckets/list.ts index 83a3592..f59b0b8 100644 --- a/src/lib/buckets/list.ts +++ b/src/lib/buckets/list.ts @@ -1,9 +1,15 @@ import { getStorageConfig } from '@auth/provider.js'; import { getBucketInfo, listBuckets } from '@tigrisdata/storage'; import { failWithError } from '@utils/exit.js'; -import { formatOutput } from '@utils/format.js'; -import { msg, printEmpty, printStart, printSuccess } from '@utils/messages.js'; -import { getFormat, getOption } from '@utils/options.js'; +import { formatOutput, formatPaginatedOutput } from '@utils/format.js'; +import { + msg, + printEmpty, + printPaginationHint, + printStart, + printSuccess, +} from '@utils/messages.js'; +import { getFormat, getOption, getPaginationOptions } from '@utils/options.js'; const context = msg('buckets', 'list'); @@ -12,9 +18,24 @@ export default async function list(options: Record) { const format = getFormat(options); const forksOf = getOption(options, ['forks-of', 'forksOf']); + const { limit, pageToken, isPaginated } = getPaginationOptions(options); const config = await getStorageConfig(); - const { data, error } = await listBuckets({ config }); + if (forksOf && isPaginated) { + console.warn( + '⚠ Pagination flags are ignored when --forks-of is used (all buckets are fetched for filtering)' + ); + } + + const { data, error } = await listBuckets({ + ...(forksOf || !isPaginated + ? {} + : { + ...(limit !== undefined ? { limit } : {}), + ...(pageToken ? { paginationToken: pageToken } : {}), + }), + config, + }); if (error) { failWithError(context, error); @@ -71,11 +92,24 @@ export default async function list(options: Record) { created: bucket.creationDate, })); - const output = formatOutput(buckets, format!, 'buckets', 'bucket', [ + const columns = [ { key: 'name', header: 'Name' }, { key: 'created', header: 'Created' }, - ]); + ]; + + const nextToken = data.paginationToken || undefined; + + const output = isPaginated + ? formatPaginatedOutput(buckets, format!, 'buckets', 'bucket', columns, { + paginationToken: nextToken, + }) + : formatOutput(buckets, format!, 'buckets', 'bucket', columns); console.log(output); + + if (isPaginated && format !== 'json' && format !== 'xml') { + printPaginationHint(nextToken); + } + printSuccess(context, { count: buckets.length }); } diff --git a/src/lib/iam/policies/list.ts b/src/lib/iam/policies/list.ts index 919cbe0..5004e0e 100644 --- a/src/lib/iam/policies/list.ts +++ b/src/lib/iam/policies/list.ts @@ -1,9 +1,15 @@ import { getOAuthIAMConfig } from '@auth/iam.js'; import { listPolicies } from '@tigrisdata/iam'; import { failWithError } from '@utils/exit.js'; -import { formatOutput } from '@utils/format.js'; -import { msg, printEmpty, printStart, printSuccess } from '@utils/messages.js'; -import { getFormat } from '@utils/options.js'; +import { formatOutput, formatPaginatedOutput } from '@utils/format.js'; +import { + msg, + printEmpty, + printPaginationHint, + printStart, + printSuccess, +} from '@utils/messages.js'; +import { getFormat, getPaginationOptions } from '@utils/options.js'; const context = msg('iam policies', 'list'); @@ -11,10 +17,13 @@ export default async function list(options: Record) { printStart(context); const format = getFormat(options); + const { limit, pageToken, isPaginated } = getPaginationOptions(options); const iamConfig = await getOAuthIAMConfig(context); const { data, error } = await listPolicies({ + ...(limit !== undefined ? { limit } : {}), + ...(pageToken ? { paginationToken: pageToken } : {}), config: { sessionToken: iamConfig.sessionToken, organizationId: iamConfig.organizationId, @@ -41,7 +50,7 @@ export default async function list(options: Record) { updated: policy.updateDate, })); - const output = formatOutput(policies, format!, 'policies', 'policy', [ + const columns = [ { key: 'id', header: 'ID' }, { key: 'resource', header: 'Resource' }, { key: 'name', header: 'Name' }, @@ -49,8 +58,21 @@ export default async function list(options: Record) { { key: 'attachments', header: 'Attachments' }, { key: 'created', header: 'Created' }, { key: 'updated', header: 'Updated' }, - ]); + ]; + + const nextToken = data.paginationToken || undefined; + + const output = isPaginated + ? formatPaginatedOutput(policies, format!, 'policies', 'policy', columns, { + paginationToken: nextToken, + }) + : formatOutput(policies, format!, 'policies', 'policy', columns); console.log(output); + + if (isPaginated && format !== 'json' && format !== 'xml') { + printPaginationHint(nextToken); + } + printSuccess(context, { count: policies.length }); } diff --git a/src/lib/objects/list.ts b/src/lib/objects/list.ts index 7d80b8d..5234c0c 100644 --- a/src/lib/objects/list.ts +++ b/src/lib/objects/list.ts @@ -1,9 +1,19 @@ import { getStorageConfig } from '@auth/provider.js'; import { list } from '@tigrisdata/storage'; import { failWithError } from '@utils/exit.js'; -import { formatOutput, formatSize } from '@utils/format.js'; -import { msg, printEmpty, printStart, printSuccess } from '@utils/messages.js'; -import { getFormat, getOption } from '@utils/options.js'; +import { + formatOutput, + formatPaginatedOutput, + formatSize, +} from '@utils/format.js'; +import { + msg, + printEmpty, + printPaginationHint, + printStart, + printSuccess, +} from '@utils/messages.js'; +import { getFormat, getOption, getPaginationOptions } from '@utils/options.js'; import { parseAnyPath } from '@utils/path.js'; const context = msg('objects', 'list'); @@ -19,6 +29,7 @@ export default async function listObjects(options: Record) { 'snapshotVersion', 'snapshot', ]); + const { limit, pageToken, isPaginated } = getPaginationOptions(options); if (!bucketArg) { failWithError(context, 'Bucket name is required'); @@ -33,6 +44,8 @@ export default async function listObjects(options: Record) { const { data, error } = await list({ prefix, ...(snapshotVersion ? { snapshotVersion } : {}), + ...(limit !== undefined ? { limit } : {}), + ...(pageToken ? { paginationToken: pageToken } : {}), config: { ...config, bucket, @@ -54,12 +67,25 @@ export default async function listObjects(options: Record) { modified: item.lastModified, })); - const output = formatOutput(objects, format!, 'objects', 'object', [ + const columns = [ { key: 'key', header: 'Key' }, { key: 'size', header: 'Size' }, { key: 'modified', header: 'Modified' }, - ]); + ]; + + const nextToken = data.paginationToken || undefined; + + const output = isPaginated + ? formatPaginatedOutput(objects, format!, 'objects', 'object', columns, { + paginationToken: nextToken, + }) + : formatOutput(objects, format!, 'objects', 'object', columns); console.log(output); + + if (isPaginated && format !== 'json' && format !== 'xml') { + printPaginationHint(nextToken); + } + printSuccess(context, { count: objects.length }); } diff --git a/src/specs.yaml b/src/specs.yaml index c005ba4..e32655a 100644 --- a/src/specs.yaml +++ b/src/specs.yaml @@ -647,6 +647,11 @@ commands: default: table - name: forks-of description: Only list buckets that are forks of the named source bucket + - name: limit + description: Maximum number of items to return per page + - name: page-token + description: Pagination token from a previous request to fetch the next page + alias: pt # create - name: create description: Create a new bucket with optional access, tier, and location settings @@ -1182,6 +1187,11 @@ commands: - name: snapshot-version description: Read from a specific bucket snapshot. Accepts a snapshot version string or any UNIX nanosecond-precision timestamp (e.g. 1765889000501544464) alias: snapshot + - name: limit + description: Maximum number of items to return per page + - name: page-token + description: Pagination token from a previous request to fetch the next page + alias: pt # get - name: get description: Download an object by key. Prints to stdout by default, or saves to a file with --output @@ -1376,6 +1386,11 @@ commands: description: Output format options: [json, table, xml] default: table + - name: limit + description: Maximum number of items to return per page + - name: page-token + description: Pagination token from a previous request to fetch the next page + alias: pt - name: create description: Create a new access key with the given name. Returns the key ID and secret (shown only once) alias: c @@ -1503,6 +1518,11 @@ commands: description: Output format options: [json, table, xml] default: table + - name: limit + description: Maximum number of items to return per page + - name: page-token + description: Pagination token from a previous request to fetch the next page + alias: pt - name: get description: Show details for a policy including its document and attached users. If no ARN provided, shows interactive selection alias: g diff --git a/src/utils/format.ts b/src/utils/format.ts index a230828..0b41245 100644 --- a/src/utils/format.ts +++ b/src/utils/format.ts @@ -248,3 +248,60 @@ export function formatOutput>( return formatTable(items, columns); } } + +export interface PaginationMeta { + paginationToken?: string; +} + +/** + * Format output with pagination metadata. + * JSON wraps items in an object with optional paginationToken. + * XML adds a element inside the root. + * Table output is unchanged (pagination hint goes to stderr separately). + */ +export function formatPaginatedOutput>( + items: T[], + format: string, + rootElement: string, + itemElement: string, + columns: TableColumn[], + pagination: PaginationMeta +): string { + switch (format) { + case 'json': { + const result: Record = { items }; + if (pagination.paginationToken) { + result.paginationToken = pagination.paginationToken; + } + return formatJson(result); + } + case 'xml': + return formatPaginatedXml(items, rootElement, itemElement, pagination); + default: + return formatTable(items, columns); + } +} + +function formatPaginatedXml>( + items: T[], + rootElement: string, + itemElement: string, + pagination: PaginationMeta +): string { + const lines = [`<${rootElement}>`]; + + items.forEach((item) => { + lines.push(` <${itemElement}>`); + lines.push(formatXmlObject(item, ' ')); + lines.push(` `); + }); + + if (pagination.paginationToken) { + lines.push( + ` ${escapeXml(pagination.paginationToken)}` + ); + } + + lines.push(``); + return lines.join('\n'); +} diff --git a/src/utils/messages.ts b/src/utils/messages.ts index 82b9266..5c9359d 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -168,6 +168,15 @@ export function printDeprecated(message: string): void { console.warn(`⚠ Deprecated: ${message}`); } +/** + * Print a pagination hint to stderr when more pages are available. + * Shows in all modes (TTY and piped) for table/xml output. + */ +export function printPaginationHint(paginationToken?: string): void { + if (!paginationToken) return; + console.error(`\nNext page: --page-token ${paginationToken}`); +} + /** * Helper to create a message context */ diff --git a/src/utils/options.ts b/src/utils/options.ts index 612b077..79046ed 100644 --- a/src/utils/options.ts +++ b/src/utils/options.ts @@ -31,6 +31,33 @@ export function getFormat( return getOption(options, ['format'], defaultFormat) ?? defaultFormat; } +export interface PaginationOptions { + limit?: number; + pageToken?: string; + isPaginated: boolean; +} + +/** + * Extract pagination flags from command options. + * Returns isPaginated=true when at least one pagination flag was provided. + */ +export function getPaginationOptions( + options: Record +): PaginationOptions { + const rawLimit = getOption(options, ['limit']); + const limit = rawLimit !== undefined ? Number(rawLimit) : undefined; + const pageToken = getOption(options, [ + 'page-token', + 'pageToken', + 'pt', + ]); + return { + limit, + pageToken, + isPaginated: limit !== undefined || pageToken !== undefined, + }; +} + /** * Parses a boolean value from string or boolean input * - undefined → undefined diff --git a/test/utils/format.test.ts b/test/utils/format.test.ts index fe290b9..38302e6 100644 --- a/test/utils/format.test.ts +++ b/test/utils/format.test.ts @@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'; import { formatJson, formatOutput, + formatPaginatedOutput, formatSize, formatTable, formatXml, @@ -159,3 +160,90 @@ describe('formatOutput', () => { expect(result).toContain('┌'); }); }); + +describe('formatPaginatedOutput', () => { + const columns: TableColumn[] = [{ key: 'name', header: 'Name' }]; + const items = [{ name: 'test' }]; + + it('json wraps items in object with paginationToken', () => { + const result = formatPaginatedOutput( + items, + 'json', + 'Root', + 'Item', + columns, + { paginationToken: 'next-token' } + ); + const parsed = JSON.parse(result); + expect(parsed.items).toEqual(items); + expect(parsed.paginationToken).toBe('next-token'); + }); + + it('json omits paginationToken key when token is undefined', () => { + const result = formatPaginatedOutput( + items, + 'json', + 'Root', + 'Item', + columns, + {} + ); + const parsed = JSON.parse(result); + expect(parsed.items).toEqual(items); + expect(parsed).not.toHaveProperty('paginationToken'); + }); + + it('xml includes paginationToken element when token provided', () => { + const result = formatPaginatedOutput( + items, + 'xml', + 'Root', + 'Item', + columns, + { paginationToken: 'abc123' } + ); + expect(result).toContain(''); + expect(result).toContain(''); + expect(result).toContain('abc123'); + expect(result).toContain(''); + }); + + it('xml omits paginationToken element when token is undefined', () => { + const result = formatPaginatedOutput( + items, + 'xml', + 'Root', + 'Item', + columns, + {} + ); + expect(result).toContain(''); + expect(result).not.toContain(''); + }); + + it('xml escapes special characters in paginationToken', () => { + const result = formatPaginatedOutput( + items, + 'xml', + 'Root', + 'Item', + columns, + { paginationToken: 'a&b { + const result = formatPaginatedOutput( + items, + 'table', + 'Root', + 'Item', + columns, + { paginationToken: 'next-token' } + ); + expect(result).toContain('┌'); + expect(result).toContain('Name'); + expect(result).not.toContain('next-token'); + }); +}); diff --git a/test/utils/options.test.ts b/test/utils/options.test.ts index d4282a5..ccb8831 100644 --- a/test/utils/options.test.ts +++ b/test/utils/options.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { getOption } from '../../src/utils/options.js'; +import { getOption, getPaginationOptions } from '../../src/utils/options.js'; describe('getOption', () => { it('should return value for first matching key', () => { @@ -57,3 +57,71 @@ describe('getOption', () => { expect(result).toEqual(['a.txt', 'b.txt']); }); }); + +describe('getPaginationOptions', () => { + it('returns isPaginated=false when no pagination flags provided', () => { + const result = getPaginationOptions({ format: 'json' }); + expect(result).toEqual({ + limit: undefined, + pageToken: undefined, + isPaginated: false, + }); + }); + + it('extracts limit and sets isPaginated=true', () => { + const result = getPaginationOptions({ limit: 10 }); + expect(result).toEqual({ + limit: 10, + pageToken: undefined, + isPaginated: true, + }); + }); + + it('extracts page-token (kebab-case) and sets isPaginated=true', () => { + const result = getPaginationOptions({ 'page-token': 'abc123' }); + expect(result).toEqual({ + limit: undefined, + pageToken: 'abc123', + isPaginated: true, + }); + }); + + it('extracts pageToken (camelCase from Commander) and sets isPaginated=true', () => { + const result = getPaginationOptions({ pageToken: 'abc123' }); + expect(result).toEqual({ + limit: undefined, + pageToken: 'abc123', + isPaginated: true, + }); + }); + + it('extracts both limit and page-token', () => { + const result = getPaginationOptions({ + limit: 25, + pageToken: 'token-xyz', + }); + expect(result).toEqual({ + limit: 25, + pageToken: 'token-xyz', + isPaginated: true, + }); + }); + + it('extracts pt alias', () => { + const result = getPaginationOptions({ pt: 'short-token' }); + expect(result).toEqual({ + limit: undefined, + pageToken: 'short-token', + isPaginated: true, + }); + }); + + it('coerces string limit from Commander to number', () => { + const result = getPaginationOptions({ limit: '10' }); + expect(result).toEqual({ + limit: 10, + pageToken: undefined, + isPaginated: true, + }); + }); +});