diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index d57e8a3b..91048864 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -16,6 +16,11 @@ jobs: packages: write id-token: write steps: + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53d58839..bb4a118f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -112,3 +112,40 @@ jobs: VERSION=${{ needs.release.outputs.version }} cache-from: type=gha cache-to: type=gha,mode=max + + mirror: + runs-on: ubuntu-latest + needs: + - release + - publish + permissions: + contents: read + packages: write + id-token: write + steps: + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + role-to-assume: ${{ secrets.PROD_AWS_ROLE }} + aws-region: 'us-east-1' + - uses: docker/login-action@v2 + with: + registry: public.ecr.aws + - uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: akhilerm/tag-push-action@v2.1.0 + with: + src: docker.io/supabase/storage-api:${{ needs.release.outputs.version }} + dst: | + public.ecr.aws/supabase/storage-api:latest + docker.io/supabase/storage-api:latest + ghcr.io/supabase/storage-api:latest + diff --git a/build.js b/build.js new file mode 100644 index 00000000..b8a9569e --- /dev/null +++ b/build.js @@ -0,0 +1,17 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { build } = require('esbuild') + +build({ + entryPoints: ['./src/**/*.ts'], + bundle: false, + outdir: 'dist', + platform: 'node', + format: 'cjs', + target: 'node20', + sourcemap: true, + tsconfig: 'tsconfig.json', + loader: { '.ts': 'ts' }, +}).catch((e) => { + console.error(e) + process.exit(1) +}) diff --git a/jest.config.js b/jest.config.js index 39a46f76..869f1b81 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,6 +4,10 @@ module.exports = { transform: { '^.+\\.(t|j)sx?$': 'ts-jest', }, + moduleNameMapper: { + '^@storage/(.*)$': '/src/storage/$1', + '^@internal/(.*)$': '/src/internal/$1', + }, setupFilesAfterEnv: ['/jest-setup.ts'], testEnvironment: 'node', testPathIgnorePatterns: ['node_modules', 'dist'], diff --git a/package-lock.json b/package-lock.json index f91e3e5a..f1bcefdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,6 +82,7 @@ "@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/parser": "^5.12.1", "babel-jest": "^29.2.2", + "esbuild": "0.21.5", "eslint": "^8.9.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-prettier": "^4.2.1", @@ -92,6 +93,7 @@ "mustache": "^4.2.0", "pino-pretty": "^8.1.0", "prettier": "^2.8.8", + "resolve-tspaths": "^0.8.19", "stream-buffers": "^3.0.2", "ts-jest": "^29.0.3", "ts-node-dev": "^1.1.8", @@ -1979,10 +1981,26 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -1996,9 +2014,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -2012,9 +2030,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -2028,9 +2046,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -2044,9 +2062,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -2060,9 +2078,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -2076,9 +2094,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -2092,9 +2110,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -2108,9 +2126,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -2124,9 +2142,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -2140,9 +2158,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -2156,9 +2174,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -2172,9 +2190,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -2188,9 +2206,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -2204,9 +2222,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -2220,9 +2238,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -2236,9 +2254,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -2252,9 +2270,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -2268,9 +2286,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -2284,9 +2302,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -2300,9 +2318,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -2316,9 +2334,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -5791,6 +5809,15 @@ } } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -6732,9 +6759,9 @@ } }, "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -6744,28 +6771,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escalade": { @@ -7184,9 +7212,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -10444,6 +10472,32 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/resolve-tspaths": { + "version": "0.8.19", + "resolved": "https://registry.npmjs.org/resolve-tspaths/-/resolve-tspaths-0.8.19.tgz", + "integrity": "sha512-yZkXNYyHdVytOkJLhbib7TFpaMVElk9auO9R1jDmOSXPUWEjy+V44VqX77RIQ+kf0UJIlAGRDK/yrbfwlu1UWg==", + "dev": true, + "dependencies": { + "ansi-colors": "4.1.3", + "commander": "12.0.0", + "fast-glob": "3.3.2" + }, + "bin": { + "resolve-tspaths": "dist/main.js" + }, + "peerDependencies": { + "typescript": ">=3.0.3" + } + }, + "node_modules/resolve-tspaths/node_modules/commander": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -11232,88 +11286,477 @@ "fsevents": "~2.3.3" } }, - "node_modules/tus-js-client": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-3.1.0.tgz", - "integrity": "sha512-Hfpc8ho4C9Lhs/OflPUA/nHUHZJUrKD5upoPBq7dYJJ9DQhWocsjJU2RZYfN16Y5n19j9dFDszwCvVZ5sfcogw==", + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "buffer-from": "^1.1.2", - "combine-errors": "^3.0.3", - "is-stream": "^2.0.0", - "js-base64": "^3.7.2", - "lodash.throttle": "^4.1.1", - "proper-lockfile": "^4.1.2", - "url-parse": "^1.5.7" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">= 0.8.0" + "node": ">=12" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/typed-emitter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-0.1.0.tgz", - "integrity": "sha512-Tfay0l6gJMP5rkil8CzGbLthukn+9BN/VXWcABVFPjOoelJ+koW8BuPZYk+h/L+lEeIp1fSzVRiWRPIjKVjPdg==" - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=4.2.0" + "node": ">=12" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">= 10.0.0" + "node": ">=12" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/tus-js-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-3.1.0.tgz", + "integrity": "sha512-Hfpc8ho4C9Lhs/OflPUA/nHUHZJUrKD5upoPBq7dYJJ9DQhWocsjJU2RZYfN16Y5n19j9dFDszwCvVZ5sfcogw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.1.2", + "combine-errors": "^3.0.3", + "is-stream": "^2.0.0", + "js-base64": "^3.7.2", + "lodash.throttle": "^4.1.1", + "proper-lockfile": "^4.1.2", + "url-parse": "^1.5.7" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-emitter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-0.1.0.tgz", + "integrity": "sha512-Tfay0l6gJMP5rkil8CzGbLthukn+9BN/VXWcABVFPjOoelJ+koW8BuPZYk+h/L+lEeIp1fSzVRiWRPIjKVjPdg==" + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "funding": [ { @@ -13178,157 +13621,164 @@ } } }, + "@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "dev": true, + "optional": true + }, "@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "dev": true, "optional": true }, @@ -15969,6 +16419,12 @@ "ajv": "^8.0.0" } }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -16676,33 +17132,34 @@ } }, "esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "escalade": { @@ -17011,9 +17468,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -19478,6 +19935,25 @@ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true }, + "resolve-tspaths": { + "version": "0.8.19", + "resolved": "https://registry.npmjs.org/resolve-tspaths/-/resolve-tspaths-0.8.19.tgz", + "integrity": "sha512-yZkXNYyHdVytOkJLhbib7TFpaMVElk9auO9R1jDmOSXPUWEjy+V44VqX77RIQ+kf0UJIlAGRDK/yrbfwlu1UWg==", + "dev": true, + "requires": { + "ansi-colors": "4.1.3", + "commander": "12.0.0", + "fast-glob": "3.3.2" + }, + "dependencies": { + "commander": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "dev": true + } + } + }, "resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -20026,6 +20502,192 @@ "fsevents": "~2.3.3", "get-tsconfig": "^4.7.2", "source-map-support": "^0.5.21" + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + } } }, "tus-js-client": { diff --git a/package.json b/package.json index 08e3c1bd..56af9e57 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "dev": "tsx watch ./src/server.ts | pino-pretty", - "build": "tsc -p tsconfig.json", + "build": "node ./build.js && resolve-tspaths", "start": "NODE_ENV=production node dist/server.js", "migration:run": "tsx ./src/scripts/migrate-call.ts", "docs:export": "tsx ./src/scripts/export-docs.ts", @@ -95,6 +95,7 @@ "@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/parser": "^5.12.1", "babel-jest": "^29.2.2", + "esbuild": "0.21.5", "eslint": "^8.9.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-prettier": "^4.2.1", @@ -105,6 +106,7 @@ "mustache": "^4.2.0", "pino-pretty": "^8.1.0", "prettier": "^2.8.8", + "resolve-tspaths": "^0.8.19", "stream-buffers": "^3.0.2", "ts-jest": "^29.0.3", "ts-node-dev": "^1.1.8", diff --git a/src/admin-app.ts b/src/admin-app.ts index 6d097dc9..722c4cc6 100644 --- a/src/admin-app.ts +++ b/src/admin-app.ts @@ -35,6 +35,8 @@ const build = (opts: FastifyServerOptions = {}, appInstance?: FastifyInstance): return reply.type(merged.contentType).send(data) }) + } else { + app.register(plugins.metrics({ enabledEndpoint: true })) } app.get('/status', async (_, response) => response.status(200).send()) diff --git a/src/app.ts b/src/app.ts index 163a81de..82d7112a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,4 @@ import fastify, { FastifyInstance, FastifyServerOptions } from 'fastify' -import fastifyMultipart from '@fastify/multipart' import fastifySwagger from '@fastify/swagger' import fastifySwaggerUi from '@fastify/swagger-ui' import { routes, schemas, plugins, setErrorHandler } from './http' @@ -30,7 +29,7 @@ const build = (opts: buildOpts = {}): FastifyInstance => { info: { title: 'Supabase Storage API', description: 'API documentation for Supabase Storage', - version: '0.0.1', + version: version, }, tags: [ { name: 'object', description: 'Object end-points' }, diff --git a/src/http/error-handler.ts b/src/http/error-handler.ts index 5fdec45f..c4f6081a 100644 --- a/src/http/error-handler.ts +++ b/src/http/error-handler.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from 'fastify' -import { ErrorCode, isRenderableError } from '../storage' import { FastifyError } from '@fastify/error' import { DatabaseError } from 'pg' +import { ErrorCode, isRenderableError } from '@internal/errors' /** * The global error handler for all the uncaught exceptions within a request. diff --git a/src/http/plugins/db.ts b/src/http/plugins/db.ts index a34b1808..35697ae1 100644 --- a/src/http/plugins/db.ts +++ b/src/http/plugins/db.ts @@ -1,4 +1,5 @@ import fastifyPlugin from 'fastify-plugin' +import { getConfig, MultitenantMigrationStrategy } from '../../config' import { areMigrationsUpToDate, getServiceKeyUser, @@ -9,11 +10,10 @@ import { getPostgresConnection, progressiveMigrations, runMigrationsOnTenant, -} from '../../database' -import { verifyJWT } from '../../auth' -import { logSchema } from '../../monitoring' -import { getConfig, MultitenantMigrationStrategy } from '../../config' -import { createMutexByKey } from '../../concurrency' +} from '@internal/database' +import { verifyJWT } from '@internal/auth' +import { logSchema } from '@internal/monitoring' +import { createMutexByKey } from '@internal/concurrency' declare module 'fastify' { interface FastifyRequest { diff --git a/src/http/plugins/jwt.ts b/src/http/plugins/jwt.ts index 1c1c7340..a3633932 100644 --- a/src/http/plugins/jwt.ts +++ b/src/http/plugins/jwt.ts @@ -1,8 +1,9 @@ import fastifyPlugin from 'fastify-plugin' -import { verifyJWT } from '../../auth' -import { getJwtSecret } from '../../database' import { JwtPayload } from 'jsonwebtoken' -import { ERRORS } from '../../storage' + +import { verifyJWT } from '@internal/auth' +import { getJwtSecret } from '@internal/database' +import { ERRORS } from '@internal/errors' declare module 'fastify' { interface FastifyRequest { diff --git a/src/http/plugins/log-request.ts b/src/http/plugins/log-request.ts index c943385c..0de1866b 100644 --- a/src/http/plugins/log-request.ts +++ b/src/http/plugins/log-request.ts @@ -1,5 +1,5 @@ import fastifyPlugin from 'fastify-plugin' -import { logSchema, redactQueryParamFromRequest } from '../../monitoring' +import { logSchema, redactQueryParamFromRequest } from '@internal/monitoring' import { trace } from '@opentelemetry/api' interface RequestLoggerOptions { diff --git a/src/http/plugins/metrics.ts b/src/http/plugins/metrics.ts index 8693ff06..d5c30501 100644 --- a/src/http/plugins/metrics.ts +++ b/src/http/plugins/metrics.ts @@ -1,5 +1,5 @@ import fastifyPlugin from 'fastify-plugin' -import { MetricsRegistrar } from '../../monitoring/metrics' +import { MetricsRegistrar } from '@internal/monitoring/metrics' import fastifyMetrics from 'fastify-metrics' import { getConfig } from '../../config' diff --git a/src/http/plugins/signature-v4.ts b/src/http/plugins/signature-v4.ts index 8e6bb9ca..cf7f01fc 100644 --- a/src/http/plugins/signature-v4.ts +++ b/src/http/plugins/signature-v4.ts @@ -1,9 +1,10 @@ import { FastifyInstance, FastifyRequest } from 'fastify' import fastifyPlugin from 'fastify-plugin' -import { getS3CredentialsByAccessKey, getTenantConfig } from '../../database' -import { ClientSignature, SignatureV4 } from '../../storage/protocols/s3' -import { ERRORS } from '../../storage' -import { signJWT, verifyJWT } from '../../auth' +import { getS3CredentialsByAccessKey, getTenantConfig } from '@internal/database' +import { ClientSignature, SignatureV4 } from '@storage/protocols/s3' +import { signJWT, verifyJWT } from '@internal/auth' +import { ERRORS } from '@internal/errors' + import { getConfig } from '../../config' const { @@ -35,14 +36,13 @@ export const signatureV4 = fastifyPlugin(async function (fastify: FastifyInstanc token, } = await createServerSignature(request.tenantId, clientSignature) - const isVerified = signatureV4.verify({ + const isVerified = signatureV4.verify(clientSignature, { url: request.url, body: request.body as string | ReadableStream | Buffer, headers: request.headers as Record, method: request.method, query: request.query as Record, prefix: s3ProtocolPrefix, - clientSignature: clientSignature, }) if (!isVerified && !sessionToken) { diff --git a/src/http/plugins/storage.ts b/src/http/plugins/storage.ts index cb32a15f..5dd95d2d 100644 --- a/src/http/plugins/storage.ts +++ b/src/http/plugins/storage.ts @@ -1,7 +1,7 @@ import fastifyPlugin from 'fastify-plugin' -import { StorageBackendAdapter, createStorageBackend } from '../../storage/backend' -import { Storage } from '../../storage' -import { StorageKnexDB } from '../../storage/database' +import { StorageBackendAdapter, createStorageBackend } from '@storage/backend' +import { Storage } from '@storage/storage' +import { StorageKnexDB } from '@storage/database' import { getConfig } from '../../config' declare module 'fastify' { diff --git a/src/http/plugins/tenant-feature.ts b/src/http/plugins/tenant-feature.ts index 019c3a77..4d77b5b9 100644 --- a/src/http/plugins/tenant-feature.ts +++ b/src/http/plugins/tenant-feature.ts @@ -1,6 +1,7 @@ import fastifyPlugin from 'fastify-plugin' +import { Features, getFeatures } from '@internal/database' + import { getConfig } from '../../config' -import { Features, getFeatures } from '../../database/tenant' /** * Requires a specific feature to be enabled for a given tenant. diff --git a/src/http/plugins/tracing-mode.ts b/src/http/plugins/tracing-mode.ts index f716f683..431fd501 100644 --- a/src/http/plugins/tracing-mode.ts +++ b/src/http/plugins/tracing-mode.ts @@ -1,5 +1,6 @@ import fastifyPlugin from 'fastify-plugin' -import { getTenantConfig } from '../../database' +import { getTenantConfig } from '@internal/database' + import { getConfig } from '../../config' declare module 'fastify' { diff --git a/src/http/generic-routes.ts b/src/http/routes-helper.ts similarity index 100% rename from src/http/generic-routes.ts rename to src/http/routes-helper.ts diff --git a/src/http/routes/admin/migrations.ts b/src/http/routes/admin/migrations.ts index 7b5f1ac7..64d4ab7c 100644 --- a/src/http/routes/admin/migrations.ts +++ b/src/http/routes/admin/migrations.ts @@ -1,8 +1,9 @@ import { FastifyInstance } from 'fastify' +import { Queue } from '@internal/queue' +import { multitenantKnex, runMigrationsOnAllTenants } from '@internal/database' +import { RunMigrationsOnTenants } from '@storage/events' import apiKey from '../../plugins/apikey' -import { Queue, RunMigrationsOnTenants } from '../../../queue' import { getConfig } from '../../../config' -import { multitenantKnex, runMigrationsOnAllTenants } from '../../../database' const { pgQueueEnable } = getConfig() diff --git a/src/http/routes/admin/s3.ts b/src/http/routes/admin/s3.ts index 947d8580..6e78f7c8 100644 --- a/src/http/routes/admin/s3.ts +++ b/src/http/routes/admin/s3.ts @@ -1,6 +1,10 @@ import { FastifyInstance, RequestGenericInterface } from 'fastify' import apiKey from '../../plugins/apikey' -import { createS3Credentials, deleteS3Credential, listS3Credentials } from '../../../database' +import { + createS3Credentials, + deleteS3Credential, + listS3Credentials, +} from '../../../internal/database' import { FromSchema } from 'json-schema-to-ts' const createCredentialsSchema = { diff --git a/src/http/routes/admin/tenants.ts b/src/http/routes/admin/tenants.ts index adcd677b..9bdcea3b 100644 --- a/src/http/routes/admin/tenants.ts +++ b/src/http/routes/admin/tenants.ts @@ -1,7 +1,7 @@ import { FastifyInstance, RequestGenericInterface } from 'fastify' import { FromSchema } from 'json-schema-to-ts' import apiKey from '../../plugins/apikey' -import { decrypt, encrypt } from '../../../auth' +import { decrypt, encrypt } from '../../../internal/auth' import { deleteTenantConfig, TenantMigrationStatus, @@ -9,7 +9,7 @@ import { lastMigrationName, runMigrationsOnTenant, progressiveMigrations, -} from '../../../database' +} from '../../../internal/database' import { dbSuperUser, storage } from '../../plugins' const patchSchema = { diff --git a/src/http/routes/bucket/createBucket.ts b/src/http/routes/bucket/createBucket.ts index 6ca57987..15144857 100644 --- a/src/http/routes/bucket/createBucket.ts +++ b/src/http/routes/bucket/createBucket.ts @@ -1,7 +1,7 @@ import { FastifyInstance, FastifyRequest } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const createBucketBodySchema = { diff --git a/src/http/routes/bucket/deleteBucket.ts b/src/http/routes/bucket/deleteBucket.ts index f16645a5..bf3463bc 100644 --- a/src/http/routes/bucket/deleteBucket.ts +++ b/src/http/routes/bucket/deleteBucket.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema, createResponse } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema, createResponse } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const deleteBucketParamsSchema = { diff --git a/src/http/routes/bucket/emptyBucket.ts b/src/http/routes/bucket/emptyBucket.ts index 6801b7b2..4ae3482b 100644 --- a/src/http/routes/bucket/emptyBucket.ts +++ b/src/http/routes/bucket/emptyBucket.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema, createResponse } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema, createResponse } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const emptyBucketParamsSchema = { diff --git a/src/http/routes/bucket/getAllBuckets.ts b/src/http/routes/bucket/getAllBuckets.ts index 4ade6fcc..778e0446 100644 --- a/src/http/routes/bucket/getAllBuckets.ts +++ b/src/http/routes/bucket/getAllBuckets.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from 'fastify' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' -import { bucketSchema } from '../../../storage/schemas' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' +import { bucketSchema } from '@storage/schemas' import { ROUTE_OPERATIONS } from '../operations' const successResponseSchema = { diff --git a/src/http/routes/bucket/getBucket.ts b/src/http/routes/bucket/getBucket.ts index c87edc91..dbd5c8fb 100644 --- a/src/http/routes/bucket/getBucket.ts +++ b/src/http/routes/bucket/getBucket.ts @@ -1,8 +1,8 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { bucketSchema } from '../../../storage/schemas' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema } from '../../routes-helper' +import { bucketSchema } from '@storage/schemas' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const getBucketParamsSchema = { diff --git a/src/http/routes/bucket/updateBucket.ts b/src/http/routes/bucket/updateBucket.ts index d7dd0694..13d3db8b 100644 --- a/src/http/routes/bucket/updateBucket.ts +++ b/src/http/routes/bucket/updateBucket.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema, createResponse } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema, createResponse } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const updateBucketBodySchema = { diff --git a/src/http/routes/object/copyObject.ts b/src/http/routes/object/copyObject.ts index 2512939a..a3ba0174 100644 --- a/src/http/routes/object/copyObject.ts +++ b/src/http/routes/object/copyObject.ts @@ -1,7 +1,7 @@ import { FastifyInstance, FastifyRequest } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const copyRequestBodySchema = { diff --git a/src/http/routes/object/createObject.ts b/src/http/routes/object/createObject.ts index 1bf65ee3..30548dfb 100644 --- a/src/http/routes/object/createObject.ts +++ b/src/http/routes/object/createObject.ts @@ -1,6 +1,6 @@ import { FastifyInstance, RequestGenericInterface } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' +import { createDefaultSchema } from '../../routes-helper' import { ROUTE_OPERATIONS } from '../operations' import fastifyMultipart from '@fastify/multipart' diff --git a/src/http/routes/object/deleteObject.ts b/src/http/routes/object/deleteObject.ts index bedd7bdb..3ed06570 100644 --- a/src/http/routes/object/deleteObject.ts +++ b/src/http/routes/object/deleteObject.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from 'fastify' import { FromSchema, JSONSchema } from 'json-schema-to-ts' -import { createDefaultSchema, createResponse } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema, createResponse } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const deleteObjectParamsSchema = { diff --git a/src/http/routes/object/deleteObjects.ts b/src/http/routes/object/deleteObjects.ts index ffbeba94..438fbb00 100644 --- a/src/http/routes/object/deleteObjects.ts +++ b/src/http/routes/object/deleteObjects.ts @@ -1,8 +1,8 @@ import { FastifyInstance, FastifyRequest } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' -import { objectSchema } from '../../../storage/schemas/object' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' +import { objectSchema } from '@storage/schemas/object' import { ROUTE_OPERATIONS } from '../operations' const deleteObjectsParamsSchema = { type: 'object', diff --git a/src/http/routes/object/getObject.ts b/src/http/routes/object/getObject.ts index 04724874..8813870a 100644 --- a/src/http/routes/object/getObject.ts +++ b/src/http/routes/object/getObject.ts @@ -2,7 +2,7 @@ import { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { FromSchema } from 'json-schema-to-ts' import { IncomingMessage, Server, ServerResponse } from 'http' import { getConfig } from '../../../config' -import { AuthenticatedRangeRequest } from '../../request' +import { AuthenticatedRangeRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const { storageS3Bucket } = getConfig() diff --git a/src/http/routes/object/getObjectInfo.ts b/src/http/routes/object/getObjectInfo.ts index 6bf0cb22..03568827 100644 --- a/src/http/routes/object/getObjectInfo.ts +++ b/src/http/routes/object/getObjectInfo.ts @@ -2,8 +2,8 @@ import { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { FromSchema } from 'json-schema-to-ts' import { IncomingMessage, Server, ServerResponse } from 'http' import { getConfig } from '../../../config' -import { AuthenticatedRangeRequest } from '../../request' -import { Obj } from '../../../storage/schemas' +import { AuthenticatedRangeRequest } from '../../types' +import { Obj } from '@storage/schemas' import { ROUTE_OPERATIONS } from '../operations' const { storageS3Bucket } = getConfig() diff --git a/src/http/routes/object/getSignedObject.ts b/src/http/routes/object/getSignedObject.ts index ec9661e7..07929663 100644 --- a/src/http/routes/object/getSignedObject.ts +++ b/src/http/routes/object/getSignedObject.ts @@ -1,10 +1,10 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' import { getConfig } from '../../../config' -import { SignedToken, verifyJWT } from '../../../auth' -import { ERRORS } from '../../../storage' -import { getJwtSecret } from '../../../database/tenant' +import { SignedToken, verifyJWT } from '../../../internal/auth' +import { getJwtSecret } from '../../../internal/database' import { ROUTE_OPERATIONS } from '../operations' +import { ERRORS } from '../../../internal/errors' const { storageS3Bucket } = getConfig() diff --git a/src/http/routes/object/getSignedURL.ts b/src/http/routes/object/getSignedURL.ts index 0342e29e..7ba57a3c 100644 --- a/src/http/routes/object/getSignedURL.ts +++ b/src/http/routes/object/getSignedURL.ts @@ -1,10 +1,10 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' -import { ImageRenderer } from '../../../storage/renderer' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' +import { ImageRenderer } from '@storage/renderer' import { transformationOptionsSchema } from '../../schemas/transformations' -import { isImageTransformationEnabled } from '../../../storage/limits' +import { isImageTransformationEnabled } from '@storage/limits' import { ROUTE_OPERATIONS } from '../operations' const getSignedURLParamsSchema = { diff --git a/src/http/routes/object/getSignedURLs.ts b/src/http/routes/object/getSignedURLs.ts index 38ef1808..d73af320 100644 --- a/src/http/routes/object/getSignedURLs.ts +++ b/src/http/routes/object/getSignedURLs.ts @@ -1,7 +1,7 @@ import { FastifyInstance, FastifyRequest } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const getSignedURLsParamsSchema = { diff --git a/src/http/routes/object/getSignedUploadURL.ts b/src/http/routes/object/getSignedUploadURL.ts index b2943109..5a68afa3 100644 --- a/src/http/routes/object/getSignedUploadURL.ts +++ b/src/http/routes/object/getSignedUploadURL.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { getConfig } from '../../../config' import { ROUTE_OPERATIONS } from '../operations' diff --git a/src/http/routes/object/listObjects.ts b/src/http/routes/object/listObjects.ts index 0f741a78..e4d85b2f 100644 --- a/src/http/routes/object/listObjects.ts +++ b/src/http/routes/object/listObjects.ts @@ -1,8 +1,8 @@ import { FastifyInstance } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' -import { objectSchema } from '../../../storage/schemas' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' +import { objectSchema } from '@storage/schemas' import { ROUTE_OPERATIONS } from '../operations' const searchRequestParamsSchema = { diff --git a/src/http/routes/object/moveObject.ts b/src/http/routes/object/moveObject.ts index 6757a013..0edcbf6d 100644 --- a/src/http/routes/object/moveObject.ts +++ b/src/http/routes/object/moveObject.ts @@ -1,7 +1,7 @@ import { FastifyInstance, FastifyRequest } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' -import { AuthenticatedRequest } from '../../request' +import { createDefaultSchema } from '../../routes-helper' +import { AuthenticatedRequest } from '../../types' import { ROUTE_OPERATIONS } from '../operations' const moveObjectsBodySchema = { diff --git a/src/http/routes/object/updateObject.ts b/src/http/routes/object/updateObject.ts index d95c73a1..81511540 100644 --- a/src/http/routes/object/updateObject.ts +++ b/src/http/routes/object/updateObject.ts @@ -1,6 +1,6 @@ import { FastifyInstance, RequestGenericInterface } from 'fastify' import { FromSchema } from 'json-schema-to-ts' -import { createDefaultSchema } from '../../generic-routes' +import { createDefaultSchema } from '../../routes-helper' import { ROUTE_OPERATIONS } from '../operations' import fastifyMultipart from '@fastify/multipart' diff --git a/src/http/routes/render/renderAuthenticatedImage.ts b/src/http/routes/render/renderAuthenticatedImage.ts index 2ac52dec..b86d0717 100644 --- a/src/http/routes/render/renderAuthenticatedImage.ts +++ b/src/http/routes/render/renderAuthenticatedImage.ts @@ -1,7 +1,7 @@ import { getConfig } from '../../../config' import { FromSchema } from 'json-schema-to-ts' import { FastifyInstance } from 'fastify' -import { ImageRenderer } from '../../../storage/renderer' +import { ImageRenderer } from '@storage/renderer' import { transformationOptionsSchema } from '../../schemas/transformations' import { ROUTE_OPERATIONS } from '../operations' diff --git a/src/http/routes/render/renderPublicImage.ts b/src/http/routes/render/renderPublicImage.ts index 203aed65..092564b4 100644 --- a/src/http/routes/render/renderPublicImage.ts +++ b/src/http/routes/render/renderPublicImage.ts @@ -1,7 +1,7 @@ import { getConfig } from '../../../config' import { FromSchema } from 'json-schema-to-ts' import { FastifyInstance } from 'fastify' -import { ImageRenderer } from '../../../storage/renderer' +import { ImageRenderer } from '@storage/renderer' import { transformationOptionsSchema } from '../../schemas/transformations' import { ROUTE_OPERATIONS } from '../operations' diff --git a/src/http/routes/render/renderSignedImage.ts b/src/http/routes/render/renderSignedImage.ts index 9f1f2093..e9625ed5 100644 --- a/src/http/routes/render/renderSignedImage.ts +++ b/src/http/routes/render/renderSignedImage.ts @@ -1,10 +1,12 @@ import { FromSchema } from 'json-schema-to-ts' import { FastifyInstance } from 'fastify' + +import { SignedToken, verifyJWT } from '@internal/auth' +import { getJwtSecret } from '@internal/database' +import { ERRORS } from '@internal/errors' + +import { ImageRenderer } from '@storage/renderer' import { getConfig } from '../../../config' -import { ImageRenderer } from '../../../storage/renderer' -import { SignedToken, verifyJWT } from '../../../auth' -import { ERRORS } from '../../../storage' -import { getJwtSecret } from '../../../database/tenant' import { ROUTE_OPERATIONS } from '../operations' const { storageS3Bucket } = getConfig() diff --git a/src/http/routes/s3/commands/abort-multipart-upload.ts b/src/http/routes/s3/commands/abort-multipart-upload.ts index 3c2610be..808aaaa6 100644 --- a/src/http/routes/s3/commands/abort-multipart-upload.ts +++ b/src/http/routes/s3/commands/abort-multipart-upload.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/complete-multipart-upload.ts b/src/http/routes/s3/commands/complete-multipart-upload.ts index 6029e756..f3387d36 100644 --- a/src/http/routes/s3/commands/complete-multipart-upload.ts +++ b/src/http/routes/s3/commands/complete-multipart-upload.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/copy-object.ts b/src/http/routes/s3/commands/copy-object.ts index c98b266d..1f7932cb 100644 --- a/src/http/routes/s3/commands/copy-object.ts +++ b/src/http/routes/s3/commands/copy-object.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/create-bucket.ts b/src/http/routes/s3/commands/create-bucket.ts index 091b7a06..0d825b78 100644 --- a/src/http/routes/s3/commands/create-bucket.ts +++ b/src/http/routes/s3/commands/create-bucket.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/create-multipart-upload.ts b/src/http/routes/s3/commands/create-multipart-upload.ts index 2c4c091d..391a85cc 100644 --- a/src/http/routes/s3/commands/create-multipart-upload.ts +++ b/src/http/routes/s3/commands/create-multipart-upload.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/delete-bucket.ts b/src/http/routes/s3/commands/delete-bucket.ts index 6b519318..17315fe3 100644 --- a/src/http/routes/s3/commands/delete-bucket.ts +++ b/src/http/routes/s3/commands/delete-bucket.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/delete-object.ts b/src/http/routes/s3/commands/delete-object.ts index e912d417..4ee6b0d2 100644 --- a/src/http/routes/s3/commands/delete-object.ts +++ b/src/http/routes/s3/commands/delete-object.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/get-bucket.ts b/src/http/routes/s3/commands/get-bucket.ts index d96746b0..7703b6b2 100644 --- a/src/http/routes/s3/commands/get-bucket.ts +++ b/src/http/routes/s3/commands/get-bucket.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/get-object.ts b/src/http/routes/s3/commands/get-object.ts index 243bb1a2..180bcf9f 100644 --- a/src/http/routes/s3/commands/get-object.ts +++ b/src/http/routes/s3/commands/get-object.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/head-bucket.ts b/src/http/routes/s3/commands/head-bucket.ts index b008faa5..acdb20e6 100644 --- a/src/http/routes/s3/commands/head-bucket.ts +++ b/src/http/routes/s3/commands/head-bucket.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/head-object.ts b/src/http/routes/s3/commands/head-object.ts index e2c912db..d9c6ac75 100644 --- a/src/http/routes/s3/commands/head-object.ts +++ b/src/http/routes/s3/commands/head-object.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/list-buckets.ts b/src/http/routes/s3/commands/list-buckets.ts index f86567b3..dd520bd8 100644 --- a/src/http/routes/s3/commands/list-buckets.ts +++ b/src/http/routes/s3/commands/list-buckets.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/list-multipart-uploads.ts b/src/http/routes/s3/commands/list-multipart-uploads.ts index dda47be6..5d8c2d1e 100644 --- a/src/http/routes/s3/commands/list-multipart-uploads.ts +++ b/src/http/routes/s3/commands/list-multipart-uploads.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/list-objects.ts b/src/http/routes/s3/commands/list-objects.ts index 677631ad..b4c97e3c 100644 --- a/src/http/routes/s3/commands/list-objects.ts +++ b/src/http/routes/s3/commands/list-objects.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/list-parts.ts b/src/http/routes/s3/commands/list-parts.ts index d7117955..7f79c53b 100644 --- a/src/http/routes/s3/commands/list-parts.ts +++ b/src/http/routes/s3/commands/list-parts.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/upload-part-copy.ts b/src/http/routes/s3/commands/upload-part-copy.ts index c2b2ef68..41db976c 100644 --- a/src/http/routes/s3/commands/upload-part-copy.ts +++ b/src/http/routes/s3/commands/upload-part-copy.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/commands/upload-part.ts b/src/http/routes/s3/commands/upload-part.ts index 41c58115..3f3894ea 100644 --- a/src/http/routes/s3/commands/upload-part.ts +++ b/src/http/routes/s3/commands/upload-part.ts @@ -1,4 +1,4 @@ -import { S3ProtocolHandler } from '../../../../storage/protocols/s3/s3-handler' +import { S3ProtocolHandler } from '@storage/protocols/s3/s3-handler' import { S3Router } from '../router' import { ROUTE_OPERATIONS } from '../../operations' diff --git a/src/http/routes/s3/error-handler.ts b/src/http/routes/s3/error-handler.ts index e83752f2..a6e7fe1f 100644 --- a/src/http/routes/s3/error-handler.ts +++ b/src/http/routes/s3/error-handler.ts @@ -2,8 +2,8 @@ import { FastifyError } from '@fastify/error' import { FastifyRequest } from 'fastify/types/request' import { FastifyReply } from 'fastify/types/reply' import { S3ServiceException } from '@aws-sdk/client-s3' -import { ErrorCode, StorageBackendError } from '../../../storage' import { DatabaseError } from 'pg' +import { ErrorCode, StorageBackendError } from '@internal/errors' export const s3ErrorHandler = ( error: FastifyError | Error, diff --git a/src/http/routes/s3/router.ts b/src/http/routes/s3/router.ts index ac5d7923..e3c0b8fa 100644 --- a/src/http/routes/s3/router.ts +++ b/src/http/routes/s3/router.ts @@ -2,7 +2,7 @@ import { FastifyRequest } from 'fastify' import { FromSchema, JSONSchema } from 'json-schema-to-ts' import type { ValidateFunction } from 'ajv' import Ajv from 'ajv' -import { Storage } from '../../../storage' +import { Storage } from '@storage/storage' import { default as CreateBucket } from './commands/create-bucket' import { default as ListBucket } from './commands/list-buckets' import { default as ListObjects } from './commands/list-objects' diff --git a/src/http/routes/tus/index.ts b/src/http/routes/tus/index.ts index 6a54e6be..bbdb32ea 100644 --- a/src/http/routes/tus/index.ts +++ b/src/http/routes/tus/index.ts @@ -2,10 +2,10 @@ import { FastifyBaseLogger, FastifyInstance } from 'fastify' import fastifyPlugin from 'fastify-plugin' import * as http from 'http' import { ServerOptions, DataStore } from '@tus/server' +import { getFileSizeLimit } from '@storage/limits' +import { Storage } from '@storage/storage' import { jwt, storage, db, dbSuperUser, tracingMode } from '../../plugins' import { getConfig } from '../../../config' -import { getFileSizeLimit } from '../../../storage/limits' -import { Storage } from '../../../storage' import { TusServer, FileStore, @@ -13,7 +13,7 @@ import { PgLocker, UploadId, AlsMemoryKV, -} from '../../../storage/protocols/tus' +} from '@storage/protocols/tus' import { namingFunction, onCreate, @@ -24,10 +24,10 @@ import { getFileIdFromRequest, SIGNED_URL_SUFFIX, } from './lifecycle' -import { TenantConnection, PubSub } from '../../../database' +import { TenantConnection, PubSub } from '../../../internal/database' import { S3Store } from '@tus/s3-store' import { NodeHttpHandler } from '@smithy/node-http-handler' -import { createAgent } from '../../../storage/backend' +import { createAgent } from '@storage/backend' import { ROUTE_OPERATIONS } from '../operations' const { diff --git a/src/http/routes/tus/lifecycle.ts b/src/http/routes/tus/lifecycle.ts index 2b1d3674..736956a6 100644 --- a/src/http/routes/tus/lifecycle.ts +++ b/src/http/routes/tus/lifecycle.ts @@ -2,11 +2,13 @@ import http from 'http' import { BaseLogger } from 'pino' import { Upload } from '@tus/server' import { randomUUID } from 'crypto' -import { ERRORS, isRenderableError, Storage } from '../../../storage' +import { TenantConnection } from '@internal/database' +import { ERRORS, isRenderableError } from '@internal/errors' +import { Storage } from '@storage/storage' +import { Uploader } from '@storage/uploader' +import { UploadId } from '@storage/protocols/tus' + import { getConfig } from '../../../config' -import { Uploader } from '../../../storage/uploader' -import { TenantConnection } from '../../../database' -import { UploadId } from '../../../storage/protocols/tus' const { storageS3Bucket, tusPath } = getConfig() const reExtractFileID = /([^/]+)\/?$/ diff --git a/src/http/request.ts b/src/http/types.ts similarity index 100% rename from src/http/request.ts rename to src/http/types.ts diff --git a/src/auth/crypto.ts b/src/internal/auth/crypto.ts similarity index 93% rename from src/auth/crypto.ts rename to src/internal/auth/crypto.ts index e10089d8..ca826b65 100644 --- a/src/auth/crypto.ts +++ b/src/internal/auth/crypto.ts @@ -1,6 +1,6 @@ import AES from 'crypto-js/aes' import Utf8 from 'crypto-js/enc-utf8' -import { getConfig } from '../config' +import { getConfig } from '../../config' const { encryptionKey } = getConfig() diff --git a/src/auth/index.ts b/src/internal/auth/index.ts similarity index 100% rename from src/auth/index.ts rename to src/internal/auth/index.ts diff --git a/src/auth/jwt.ts b/src/internal/auth/jwt.ts similarity index 98% rename from src/auth/jwt.ts rename to src/internal/auth/jwt.ts index cd1283dc..beee533a 100644 --- a/src/auth/jwt.ts +++ b/src/internal/auth/jwt.ts @@ -1,8 +1,8 @@ import * as crypto from 'crypto' import jwt from 'jsonwebtoken' +import { ERRORS } from '@internal/errors' -import { getConfig } from '../config' -import { ERRORS } from '../storage' +import { getConfig } from '../../config' const { jwtAlgorithm } = getConfig() diff --git a/src/concurrency/index.ts b/src/internal/concurrency/index.ts similarity index 100% rename from src/concurrency/index.ts rename to src/internal/concurrency/index.ts diff --git a/src/concurrency/mutex.ts b/src/internal/concurrency/mutex.ts similarity index 100% rename from src/concurrency/mutex.ts rename to src/internal/concurrency/mutex.ts diff --git a/src/database/client.ts b/src/internal/database/client.ts similarity index 95% rename from src/database/client.ts rename to src/internal/database/client.ts index 2be87990..30c3c173 100644 --- a/src/database/client.ts +++ b/src/internal/database/client.ts @@ -1,7 +1,7 @@ -import { getConfig } from '../config' +import { getConfig } from '../../config' import { getTenantConfig } from './tenant' -import { ERRORS } from '../storage' import { User, TenantConnection } from './connection' +import { ERRORS } from '@internal/errors' interface ConnectionOptions { host: string diff --git a/src/database/connection.ts b/src/internal/database/connection.ts similarity index 98% rename from src/database/connection.ts rename to src/internal/database/connection.ts index 9d54e677..0f19b63c 100644 --- a/src/database/connection.ts +++ b/src/internal/database/connection.ts @@ -3,11 +3,11 @@ import { Knex, knex } from 'knex' import { JwtPayload } from 'jsonwebtoken' import retry from 'async-retry' import TTLCache from '@isaacs/ttlcache' -import { getConfig } from '../config' +import { getConfig } from '../../config' import { DbActiveConnection, DbActivePool } from '../monitoring/metrics' -import { ERRORS } from '../storage' import KnexTimeoutError = knex.KnexTimeoutError import { logger, logSchema } from '../monitoring' +import { ERRORS } from '@internal/errors' // https://github.com/knex/knex/issues/387#issuecomment-51554522 pg.types.setTypeParser(20, 'text', parseInt) diff --git a/src/database/index.ts b/src/internal/database/index.ts similarity index 100% rename from src/database/index.ts rename to src/internal/database/index.ts diff --git a/src/database/migrations/index.ts b/src/internal/database/migrations/index.ts similarity index 100% rename from src/database/migrations/index.ts rename to src/internal/database/migrations/index.ts diff --git a/src/database/migrations/migrate.ts b/src/internal/database/migrations/migrate.ts similarity index 99% rename from src/database/migrations/migrate.ts rename to src/internal/database/migrations/migrate.ts index c00beed2..ed101ec0 100644 --- a/src/database/migrations/migrate.ts +++ b/src/internal/database/migrations/migrate.ts @@ -1,7 +1,7 @@ import { Client, ClientConfig } from 'pg' import SQL from 'sql-template-strings' import { loadMigrationFiles, MigrationError } from 'postgres-migrations' -import { getConfig, MultitenantMigrationStrategy } from '../../config' +import { getConfig, MultitenantMigrationStrategy } from '../../../config' import { logger, logSchema } from '../../monitoring' import { BasicPgClient, Migration } from 'postgres-migrations/dist/types' import { validateMigrationHashes } from 'postgres-migrations/dist/validation' @@ -9,8 +9,8 @@ import { runMigration } from 'postgres-migrations/dist/run-migration' import { searchPath } from '../connection' import { listTenantsToMigrate } from '../tenant' import { multitenantKnex } from '../multitenant-db' -import { RunMigrationsOnTenants } from '../../queue' import { ProgressiveMigrations } from './progressive' +import { RunMigrationsOnTenants } from '@storage/events' const { multitenantDatabaseUrl, diff --git a/src/database/migrations/progressive.ts b/src/internal/database/migrations/progressive.ts similarity index 98% rename from src/database/migrations/progressive.ts rename to src/internal/database/migrations/progressive.ts index 50c94f2f..4b08299e 100644 --- a/src/database/migrations/progressive.ts +++ b/src/internal/database/migrations/progressive.ts @@ -1,6 +1,6 @@ import { logger, logSchema } from '../../monitoring' import { areMigrationsUpToDate, getTenantConfig, TenantMigrationStatus } from '../tenant' -import { RunMigrationsOnTenants } from '../../queue' +import { RunMigrationsOnTenants } from '@storage/events' export class ProgressiveMigrations { protected tenants: string[] = [] diff --git a/src/database/multitenant-db.ts b/src/internal/database/multitenant-db.ts similarity index 83% rename from src/database/multitenant-db.ts rename to src/internal/database/multitenant-db.ts index 7a70c9f9..51913af2 100644 --- a/src/database/multitenant-db.ts +++ b/src/internal/database/multitenant-db.ts @@ -1,5 +1,5 @@ import Knex from 'knex' -import { getConfig } from '../config' +import { getConfig } from '../../config' const { multitenantDatabaseUrl } = getConfig() diff --git a/src/database/pubsub.ts b/src/internal/database/pubsub.ts similarity index 91% rename from src/database/pubsub.ts rename to src/internal/database/pubsub.ts index f94c328d..810c4d11 100644 --- a/src/database/pubsub.ts +++ b/src/internal/database/pubsub.ts @@ -1,5 +1,5 @@ import { PostgresPubSub } from '../pubsub' -import { getConfig } from '../config' +import { getConfig } from '../../config' import { logger } from '../monitoring' const { isMultitenant, databaseURL, multitenantDatabaseUrl } = getConfig() diff --git a/src/database/tenant.ts b/src/internal/database/tenant.ts similarity index 99% rename from src/database/tenant.ts rename to src/internal/database/tenant.ts index f1df128f..540d17c2 100644 --- a/src/database/tenant.ts +++ b/src/internal/database/tenant.ts @@ -1,14 +1,14 @@ import crypto from 'crypto' -import { getConfig } from '../config' +import { getConfig } from '../../config' import { decrypt, encrypt, verifyJWT } from '../auth' import { multitenantKnex } from './multitenant-db' -import { ERRORS } from '../storage' import { JwtPayload } from 'jsonwebtoken' import { PubSubAdapter } from '../pubsub' import { createMutexByKey } from '../concurrency' import { LRUCache } from 'lru-cache' import objectSizeOf from 'object-sizeof' import { lastMigrationName } from './migrations/migrate' +import { ERRORS } from '@internal/errors' interface TenantConfig { anonKey?: string diff --git a/src/storage/errors.ts b/src/internal/errors/codes.ts similarity index 78% rename from src/storage/errors.ts rename to src/internal/errors/codes.ts index 331b98d9..2216430b 100644 --- a/src/storage/errors.ts +++ b/src/internal/errors/codes.ts @@ -1,12 +1,4 @@ -import { S3ServiceException } from '@aws-sdk/client-s3' - -export type StorageError = { - statusCode: string - code: ErrorCode - error: string - message: string - query?: string -} +import { StorageBackendError } from './storage-error' export enum ErrorCode { NoSuchBucket = 'NoSuchBucket', @@ -377,123 +369,6 @@ export function isStorageError(errorType: ErrorCode, error: any): error is Stora return error instanceof StorageBackendError && error.code === errorType } -/** - * A renderable error is a handled error - * that we want to display to our users - */ -export interface RenderableError { - error?: string - userStatusCode?: number - render(): StorageError - getOriginalError(): unknown -} - -/** - * Determines if an error is a renderable error - * @param error - */ -export function isRenderableError(error: unknown): error is RenderableError { - return !!error && typeof error === 'object' && 'render' in error -} - -/** - * Determines if an error is an S3 error - * @param error - */ -export function isS3Error(error: unknown): error is S3ServiceException { - return !!error && typeof error === 'object' && '$metadata' in error -} - -export interface StorageErrorOptions { - code: ErrorCode - httpStatusCode: number - message: string - resource?: string - originalError?: unknown - error?: string -} - -/** - * A generic error that should be always thrown for generic exceptions - */ -export class StorageBackendError extends Error implements RenderableError { - httpStatusCode: number - originalError: unknown - userStatusCode: number - resource?: string - code: ErrorCode - metadata?: Record = {} - error?: string // backwards compatible error - - constructor(options: StorageErrorOptions) { - super(options.message) - this.code = options.code - this.httpStatusCode = options.httpStatusCode - this.userStatusCode = options.httpStatusCode === 500 ? 500 : 400 - this.message = options.message - this.originalError = options.originalError - this.resource = options.resource - this.error = options.error - Object.setPrototypeOf(this, StorageBackendError.prototype) - } - - static withStatusCode(statusCode: number, options: StorageErrorOptions) { - const error = new StorageBackendError(options) - error.userStatusCode = statusCode - return error - } - - static fromError(error?: unknown) { - let oldErrorMessage: string - let httpStatusCode: number - let message: string - let code: ErrorCode - - if (isS3Error(error)) { - code = ErrorCode.S3Error - oldErrorMessage = error.message - httpStatusCode = error.$metadata.httpStatusCode ?? 500 - message = error.name - } else if (error instanceof Error) { - code = ErrorCode.InternalError - oldErrorMessage = error.name - httpStatusCode = 500 - message = error.message - } else { - code = ErrorCode.InternalError - oldErrorMessage = 'Internal server error' - httpStatusCode = 500 - message = 'Internal server error' - } - - return new StorageBackendError({ - error: oldErrorMessage, - code: code, - httpStatusCode, - message, - originalError: error, - }) - } - - withMetadata(metadata: Record) { - this.metadata = metadata - return this - } - - render() { - return { - statusCode: this.httpStatusCode.toString(), - code: this.code, - error: this.code, - message: this.message, - } - } - - getOriginalError() { - return this.originalError - } -} - export function normalizeRawError(error: any) { if (error instanceof Error) { return { diff --git a/src/internal/errors/index.ts b/src/internal/errors/index.ts new file mode 100644 index 00000000..8a6b8775 --- /dev/null +++ b/src/internal/errors/index.ts @@ -0,0 +1,3 @@ +export * from './storage-error' +export * from './codes' +export * from './renderable' diff --git a/src/internal/errors/renderable.ts b/src/internal/errors/renderable.ts new file mode 100644 index 00000000..21e47c48 --- /dev/null +++ b/src/internal/errors/renderable.ts @@ -0,0 +1,29 @@ +import { ErrorCode } from './codes' + +export interface StorageErrorOptions { + code: ErrorCode + httpStatusCode: number + message: string + resource?: string + originalError?: unknown + error?: string +} + +export type StorageError = { + statusCode: string + code: ErrorCode + error: string + message: string + query?: string +} + +/** + * A renderable error is a handled error + * that we want to display to our users + */ +export interface RenderableError { + error?: string + userStatusCode?: number + render(): StorageError + getOriginalError(): unknown +} diff --git a/src/internal/errors/storage-error.ts b/src/internal/errors/storage-error.ts new file mode 100644 index 00000000..e446d630 --- /dev/null +++ b/src/internal/errors/storage-error.ts @@ -0,0 +1,100 @@ +import { ErrorCode } from './codes' +import { RenderableError, StorageErrorOptions } from './renderable' +import { S3ServiceException } from '@aws-sdk/client-s3' + +/** + * A generic error that should be always thrown for generic exceptions + */ +export class StorageBackendError extends Error implements RenderableError { + httpStatusCode: number + originalError: unknown + userStatusCode: number + resource?: string + code: ErrorCode + metadata?: Record = {} + error?: string // backwards compatible error + + constructor(options: StorageErrorOptions) { + super(options.message) + this.code = options.code + this.httpStatusCode = options.httpStatusCode + this.userStatusCode = options.httpStatusCode === 500 ? 500 : 400 + this.message = options.message + this.originalError = options.originalError + this.resource = options.resource + this.error = options.error + Object.setPrototypeOf(this, StorageBackendError.prototype) + } + + static withStatusCode(statusCode: number, options: StorageErrorOptions) { + const error = new StorageBackendError(options) + error.userStatusCode = statusCode + return error + } + + static fromError(error?: unknown) { + let oldErrorMessage: string + let httpStatusCode: number + let message: string + let code: ErrorCode + + if (isS3Error(error)) { + code = ErrorCode.S3Error + oldErrorMessage = error.message + httpStatusCode = error.$metadata.httpStatusCode ?? 500 + message = error.name + } else if (error instanceof Error) { + code = ErrorCode.InternalError + oldErrorMessage = error.name + httpStatusCode = 500 + message = error.message + } else { + code = ErrorCode.InternalError + oldErrorMessage = 'Internal server error' + httpStatusCode = 500 + message = 'Internal server error' + } + + return new StorageBackendError({ + error: oldErrorMessage, + code: code, + httpStatusCode, + message, + originalError: error, + }) + } + + withMetadata(metadata: Record) { + this.metadata = metadata + return this + } + + render() { + return { + statusCode: this.httpStatusCode.toString(), + code: this.code, + error: this.code, + message: this.message, + } + } + + getOriginalError() { + return this.originalError + } +} + +/** + * Determines if an error is a renderable error + * @param error + */ +export function isRenderableError(error: unknown): error is RenderableError { + return !!error && typeof error === 'object' && 'render' in error +} + +/** + * Determines if an error is an S3 error + * @param error + */ +export function isS3Error(error: unknown): error is S3ServiceException { + return !!error && typeof error === 'object' && '$metadata' in error +} diff --git a/src/monitoring/index.ts b/src/internal/monitoring/index.ts similarity index 100% rename from src/monitoring/index.ts rename to src/internal/monitoring/index.ts diff --git a/src/monitoring/logflare.ts b/src/internal/monitoring/logflare.ts similarity index 100% rename from src/monitoring/logflare.ts rename to src/internal/monitoring/logflare.ts diff --git a/src/monitoring/logger.ts b/src/internal/monitoring/logger.ts similarity index 98% rename from src/monitoring/logger.ts rename to src/internal/monitoring/logger.ts index 8eb7dd2e..8f70e672 100644 --- a/src/monitoring/logger.ts +++ b/src/internal/monitoring/logger.ts @@ -1,8 +1,8 @@ import pino, { BaseLogger } from 'pino' -import { getConfig } from '../config' +import { getConfig } from '../../config' import { FastifyReply, FastifyRequest } from 'fastify' import { URL } from 'url' -import { normalizeRawError } from '../storage' +import { normalizeRawError } from '@internal/errors' const { logLevel, logflareApiKey, logflareSourceToken, logflareEnabled, region } = getConfig() diff --git a/src/monitoring/metrics.ts b/src/internal/monitoring/metrics.ts similarity index 100% rename from src/monitoring/metrics.ts rename to src/internal/monitoring/metrics.ts diff --git a/src/monitoring/otel.ts b/src/internal/monitoring/otel.ts similarity index 99% rename from src/monitoring/otel.ts rename to src/internal/monitoring/otel.ts index b59bb93c..b966a6e2 100644 --- a/src/monitoring/otel.ts +++ b/src/internal/monitoring/otel.ts @@ -1,4 +1,4 @@ -import { getConfig } from '../config' +import { getConfig } from '../../config' const { version, diff --git a/src/pubsub/adapter.ts b/src/internal/pubsub/adapter.ts similarity index 100% rename from src/pubsub/adapter.ts rename to src/internal/pubsub/adapter.ts diff --git a/src/pubsub/index.ts b/src/internal/pubsub/index.ts similarity index 100% rename from src/pubsub/index.ts rename to src/internal/pubsub/index.ts diff --git a/src/pubsub/postgres.ts b/src/internal/pubsub/postgres.ts similarity index 100% rename from src/pubsub/postgres.ts rename to src/internal/pubsub/postgres.ts diff --git a/src/internal/queue/index.ts b/src/internal/queue/index.ts new file mode 100644 index 00000000..2de5032b --- /dev/null +++ b/src/internal/queue/index.ts @@ -0,0 +1 @@ +export * from './queue' diff --git a/src/queue/queue.ts b/src/internal/queue/queue.ts similarity index 95% rename from src/queue/queue.ts rename to src/internal/queue/queue.ts index 6710a64b..8af874b3 100644 --- a/src/queue/queue.ts +++ b/src/internal/queue/queue.ts @@ -1,7 +1,6 @@ import PgBoss, { Job, JobWithMetadata } from 'pg-boss' -import { getConfig } from '../config' -import { registerWorkers } from './workers' -import { BaseEvent, BasePayload } from './events' +import { getConfig } from '../../config' +import { BaseEvent, BasePayload } from '../../storage/events' import { QueueJobRetryFailed, QueueJobCompleted, QueueJobError } from '../monitoring/metrics' import { logger, logSchema } from '../monitoring' @@ -27,7 +26,6 @@ export abstract class Queue { pgQueueDeleteAfterDays, pgQueueArchiveCompletedAfterSeconds, pgQueueRetentionDays, - pgQueueEnableWorkers, } = getConfig() let url = pgQueueConnectionURL ?? databaseURL @@ -53,10 +51,6 @@ export abstract class Queue { expireInHours: 48, }) - if (pgQueueEnableWorkers) { - registerWorkers() - } - Queue.pgBoss.on('error', (error) => { logSchema.error(logger, '[Queue] error', { type: 'queue', diff --git a/src/queue/index.ts b/src/queue/index.ts deleted file mode 100644 index 0b96a363..00000000 --- a/src/queue/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './queue' -export * from './events' diff --git a/src/scripts/migrate-call.ts b/src/scripts/migrate-call.ts index 30ef3676..72c3d6d3 100644 --- a/src/scripts/migrate-call.ts +++ b/src/scripts/migrate-call.ts @@ -1,7 +1,7 @@ import dotenv from 'dotenv' dotenv.config() -import { runMigrationsOnTenant } from '../database' +import { runMigrationsOnTenant } from '../internal/database' ;(async () => { await runMigrationsOnTenant(process.env.DATABASE_URL as string) })() diff --git a/src/scripts/supa-script.ts b/src/scripts/supa-script.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/server.ts b/src/server.ts index e1d16e52..0dd610e1 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,4 +1,4 @@ -import './monitoring/otel' +import './internal/monitoring/otel' import { FastifyInstance } from 'fastify' import { IncomingMessage, Server, ServerResponse } from 'http' @@ -13,10 +13,37 @@ import { listenForTenantUpdate, PubSub, multitenantKnex, -} from './database' -import { logger, logSchema } from './monitoring' -import { Queue } from './queue' -;(async () => { +} from '@internal/database' +import { logger, logSchema } from '@internal/monitoring' +import { Queue } from '@internal/queue' +import { registerWorkers } from '@storage/events' + +const serverSignal = new AbortController() + +process.on('uncaughtException', (e) => { + logSchema.error(logger, 'uncaught exception', { + type: 'uncaughtException', + error: e, + }) + process.exit(1) +}) + +// Start API server +main() + .then(() => { + logger.info('[Server] Started Successfully') + }) + .catch((e) => { + logSchema.error(logger, 'Server shutdown with error', { + type: 'startupError', + error: e, + }) + }) + +/** + * Start Storage API server + */ +async function main() { const { databaseURL, isMultitenant, @@ -26,11 +53,11 @@ import { Queue } from './queue' port, host, pgQueueEnable, + pgQueueEnableWorkers, exposeDocs, } = getConfig() - const serverSignal = new AbortController() - + // Migrations if (isMultitenant) { await runMultitenantMigrations() await listenForTenantUpdate(PubSub) @@ -39,11 +66,18 @@ import { Queue } from './queue' await runMigrationsOnTenant(databaseURL) } + // Queue if (pgQueueEnable) { + if (pgQueueEnableWorkers) { + registerWorkers() + } await Queue.init() } - let adminApp: FastifyInstance | undefined = undefined + // Pubsub + await PubSub.connect() + + // HTTP Server const app: FastifyInstance = build({ logger, disableRequestLogging: true, @@ -51,8 +85,6 @@ import { Queue } from './queue' requestIdHeader: requestTraceHeader, }) - await PubSub.connect() - app.listen({ port, host }, (err) => { if (err) { logSchema.error(logger, `Server failed to start`, { @@ -63,6 +95,9 @@ import { Queue } from './queue' } }) + // HTTP Server Admin + let adminApp: FastifyInstance | undefined = undefined + if (isMultitenant) { adminApp = buildAdmin( { @@ -84,18 +119,10 @@ import { Queue } from './queue' } } - process.on('uncaughtException', (e) => { - logSchema.error(logger, 'uncaught exception', { - type: 'uncaughtException', - error: e, - }) - process.exit(1) - }) - process.on('SIGTERM', async () => { try { logger.info('Received SIGTERM, shutting down') - await Promise.all([app.close(), adminApp?.close()]) + await Promise.allSettled([app.close(), adminApp?.close()]) await Promise.allSettled([ serverSignal.abort(), Queue.stop(), @@ -115,4 +142,4 @@ import { Queue } from './queue' process.exit(1) } }) -})() +} diff --git a/src/storage/backend/adapter.ts b/src/storage/backend/adapter.ts index 0b72a217..d7927d02 100644 --- a/src/storage/backend/adapter.ts +++ b/src/storage/backend/adapter.ts @@ -1,4 +1,4 @@ -import stream, { Readable } from 'stream' +import { Readable } from 'stream' import { getConfig } from '../../config' /** diff --git a/src/storage/backend/file.ts b/src/storage/backend/file.ts index 40625334..199fac14 100644 --- a/src/storage/backend/file.ts +++ b/src/storage/backend/file.ts @@ -14,7 +14,7 @@ import { BrowserCacheHeaders, UploadPart, } from './adapter' -import { ERRORS, StorageBackendError } from '../errors' +import { ERRORS, StorageBackendError } from '@internal/errors' import { randomUUID } from 'crypto' import fsExtra from 'fs-extra' const pipeline = promisify(stream.pipeline) diff --git a/src/storage/backend/s3.ts b/src/storage/backend/s3.ts index 4a99ab68..06dcd252 100644 --- a/src/storage/backend/s3.ts +++ b/src/storage/backend/s3.ts @@ -26,7 +26,7 @@ import { UploadPart, } from './adapter' import { getSignedUrl } from '@aws-sdk/s3-request-presigner' -import { ERRORS, StorageBackendError } from '../errors' +import { ERRORS, StorageBackendError } from '@internal/errors' import { getConfig } from '../../config' import Agent, { HttpsAgent } from 'agentkeepalive' import { Readable } from 'stream' diff --git a/src/storage/database/adapter.ts b/src/storage/database/adapter.ts index 593cbf64..6c97e278 100644 --- a/src/storage/database/adapter.ts +++ b/src/storage/database/adapter.ts @@ -1,6 +1,6 @@ import { Bucket, S3MultipartUpload, Obj, S3PartUpload } from '../schemas' import { ObjectMetadata } from '../backend' -import { TenantConnection } from '../../database/connection' +import { TenantConnection } from '@internal/database' export interface SearchObjectOption { search?: string diff --git a/src/storage/database/knex.ts b/src/storage/database/knex.ts index 7d345498..6ab3261c 100644 --- a/src/storage/database/knex.ts +++ b/src/storage/database/knex.ts @@ -6,7 +6,7 @@ import { RenderableError, StorageBackendError, StorageErrorOptions, -} from '../errors' +} from '@internal/errors' import { ObjectMetadata } from '../backend' import { Knex } from 'knex' import { @@ -17,8 +17,8 @@ import { SearchObjectOption, } from './adapter' import { DatabaseError } from 'pg' -import { TenantConnection } from '../../database' -import { DbQueryPerformance } from '../../monitoring/metrics' +import { TenantConnection } from '@internal/database' +import { DbQueryPerformance } from '@internal/monitoring/metrics' import { isUuid } from '../limits' /** diff --git a/src/queue/events/base-event.ts b/src/storage/events/base-event.ts similarity index 93% rename from src/queue/events/base-event.ts rename to src/storage/events/base-event.ts index aaa26358..846dc20d 100644 --- a/src/queue/events/base-event.ts +++ b/src/storage/events/base-event.ts @@ -1,12 +1,12 @@ -import { Queue } from '../queue' +import { Queue } from '@internal/queue' import PgBoss, { BatchWorkOptions, Job, SendOptions, WorkOptions } from 'pg-boss' -import { getPostgresConnection, getServiceKeyUser } from '../../database' -import { Storage } from '../../storage' -import { StorageKnexDB } from '../../storage/database' -import { createAgent, createStorageBackend } from '../../storage/backend' +import { getPostgresConnection, getServiceKeyUser } from '@internal/database' +import { Storage } from '../index' +import { StorageKnexDB } from '../database' +import { createAgent, createStorageBackend } from '../backend' import { getConfig } from '../../config' -import { QueueJobScheduled, QueueJobSchedulingTime } from '../../monitoring/metrics' -import { logger } from '../../monitoring' +import { QueueJobScheduled, QueueJobSchedulingTime } from '@internal/monitoring/metrics' +import { logger } from '@internal/monitoring' export interface BasePayload { $version?: string diff --git a/src/queue/events/index.ts b/src/storage/events/index.ts similarity index 89% rename from src/queue/events/index.ts rename to src/storage/events/index.ts index 65f683ae..c90c6967 100644 --- a/src/queue/events/index.ts +++ b/src/storage/events/index.ts @@ -5,3 +5,4 @@ export * from './object-updated' export * from './object-removed' export * from './object-admin-delete' export * from './run-migrations' +export * from './workers' diff --git a/src/queue/events/object-admin-delete.ts b/src/storage/events/object-admin-delete.ts similarity index 89% rename from src/queue/events/object-admin-delete.ts rename to src/storage/events/object-admin-delete.ts index 57089212..d22f89c4 100644 --- a/src/queue/events/object-admin-delete.ts +++ b/src/storage/events/object-admin-delete.ts @@ -1,9 +1,9 @@ import { BaseEvent, BasePayload } from './base-event' import { getConfig } from '../../config' -import { Job, WorkOptions } from 'pg-boss' -import { withOptionalVersion } from '../../storage/backend' -import { logger, logSchema } from '../../monitoring' -import { Storage } from '../../storage' +import { Job, SendOptions, WorkOptions } from 'pg-boss' +import { withOptionalVersion } from '../backend' +import { logger, logSchema } from '@internal/monitoring' +import { Storage } from '../index' export interface ObjectDeleteEvent extends BasePayload { name: string @@ -23,6 +23,12 @@ export class ObjectAdminDelete extends BaseEvent { } } + static getQueueOptions(): SendOptions { + return { + priority: 10, + } + } + static async handle(job: Job) { let storage: Storage | undefined = undefined diff --git a/src/queue/events/object-created.ts b/src/storage/events/object-created.ts similarity index 94% rename from src/queue/events/object-created.ts rename to src/storage/events/object-created.ts index 224501e6..ede20611 100644 --- a/src/queue/events/object-created.ts +++ b/src/storage/events/object-created.ts @@ -1,5 +1,5 @@ import { BaseEvent, BasePayload } from './base-event' -import { ObjectMetadata } from '../../storage/backend' +import { ObjectMetadata } from '../backend' import { ObjectRemovedEvent } from './object-removed' interface ObjectCreatedEvent extends BasePayload { diff --git a/src/queue/events/object-removed.ts b/src/storage/events/object-removed.ts similarity index 100% rename from src/queue/events/object-removed.ts rename to src/storage/events/object-removed.ts diff --git a/src/queue/events/object-updated.ts b/src/storage/events/object-updated.ts similarity index 87% rename from src/queue/events/object-updated.ts rename to src/storage/events/object-updated.ts index 0b8ff4c5..98b550d9 100644 --- a/src/queue/events/object-updated.ts +++ b/src/storage/events/object-updated.ts @@ -1,5 +1,5 @@ import { BaseEvent, BasePayload } from './base-event' -import { ObjectMetadata } from '../../storage/backend' +import { ObjectMetadata } from '../backend' interface ObjectUpdatedMetadataEvent extends BasePayload { name: string diff --git a/src/queue/events/run-migrations.ts b/src/storage/events/run-migrations.ts similarity index 95% rename from src/queue/events/run-migrations.ts rename to src/storage/events/run-migrations.ts index eec84b7c..4cb2e70f 100644 --- a/src/queue/events/run-migrations.ts +++ b/src/storage/events/run-migrations.ts @@ -5,9 +5,9 @@ import { TenantMigrationStatus, updateTenantMigrationsState, runMigrationsOnTenant, -} from '../../database' +} from '@internal/database' import { JobWithMetadata, SendOptions, WorkOptions } from 'pg-boss' -import { logger, logSchema } from '../../monitoring' +import { logger, logSchema } from '@internal/monitoring' interface RunMigrationsPayload extends BasePayload { tenantId: string diff --git a/src/queue/events/webhook.ts b/src/storage/events/webhook.ts similarity index 75% rename from src/queue/events/webhook.ts rename to src/storage/events/webhook.ts index 6d990048..5e20b776 100644 --- a/src/queue/events/webhook.ts +++ b/src/storage/events/webhook.ts @@ -1,8 +1,10 @@ import { BaseEvent } from './base-event' import { Job, WorkOptions } from 'pg-boss' +import { HttpsAgent } from 'agentkeepalive' +import HttpAgent from 'agentkeepalive' import axios from 'axios' import { getConfig } from '../../config' -import { logger, logSchema } from '../../monitoring' +import { logger, logSchema } from '@internal/monitoring' const { webhookURL, @@ -26,6 +28,25 @@ interface WebhookEvent { } } +const httpAgent = webhookURL?.startsWith('https://') + ? { + httpsAgent: new HttpsAgent({ + maxSockets: 100, + }), + } + : { + httpAgent: new HttpAgent({ + maxSockets: 100, + }), + } + +const client = axios.create({ + ...httpAgent, + headers: { + ...(webhookApiKey ? { authorization: `Bearer ${webhookApiKey}` } : {}), + }, +}) + export class Webhook extends BaseEvent { static queueName = 'webhooks' @@ -59,20 +80,12 @@ export class Webhook extends BaseEvent { }) try { - await axios.post( - webhookURL, - { - type: 'Webhook', - event: job.data.event, - sentAt: new Date(), - tenant: job.data.tenant, - }, - { - headers: { - ...(webhookApiKey ? { authorization: `Bearer ${webhookApiKey}` } : {}), - }, - } - ) + await client.post(webhookURL, { + type: 'Webhook', + event: job.data.event, + sentAt: new Date(), + tenant: job.data.tenant, + }) } catch (e) { logger.error( { diff --git a/src/queue/workers.ts b/src/storage/events/workers.ts similarity index 79% rename from src/queue/workers.ts rename to src/storage/events/workers.ts index 7393ee78..775767ba 100644 --- a/src/queue/workers.ts +++ b/src/storage/events/workers.ts @@ -1,5 +1,5 @@ -import { Queue } from './queue' -import { ObjectAdminDelete, Webhook, RunMigrationsOnTenants } from './events' +import { Queue } from '@internal/queue' +import { ObjectAdminDelete, Webhook, RunMigrationsOnTenants } from './index' export function registerWorkers() { Queue.register(Webhook) diff --git a/src/storage/index.ts b/src/storage/index.ts index 298b526e..4d95f069 100644 --- a/src/storage/index.ts +++ b/src/storage/index.ts @@ -1,3 +1,4 @@ export * from './storage' export * as backends from './backend' -export * from './errors' +export * from './database' +export * from './schemas' diff --git a/src/storage/limits.ts b/src/storage/limits.ts index 692e61f1..b0d4804f 100644 --- a/src/storage/limits.ts +++ b/src/storage/limits.ts @@ -1,6 +1,9 @@ import { getConfig } from '../config' -import { getFileSizeLimit as getFileSizeLimitForTenant, getFeatures } from '../database/tenant' -import { ERRORS } from './errors' +import { + getFileSizeLimit as getFileSizeLimitForTenant, + getFeatures, +} from '../internal/database/tenant' +import { ERRORS } from '../internal/errors' const { isMultitenant, imageTransformationEnabled } = getConfig() diff --git a/src/storage/object.ts b/src/storage/object.ts index 0548d4dc..6ccd0aa8 100644 --- a/src/storage/object.ts +++ b/src/storage/object.ts @@ -1,10 +1,14 @@ +import { FastifyRequest } from 'fastify' +import { randomUUID } from 'crypto' +import { SignedUploadToken, signJWT, verifyJWT } from '@internal/auth' +import { ERRORS } from '@internal/errors' +import { getJwtSecret } from '@internal/database' + import { StorageBackendAdapter, ObjectMetadata, withOptionalVersion } from './backend' import { Database, FindObjectFilters, SearchObjectOption } from './database' import { mustBeValidKey } from './limits' -import { SignedUploadToken, signJWT, verifyJWT } from '../auth' -import { getConfig } from '../config' -import { FastifyRequest } from 'fastify' import { Uploader } from './uploader' +import { getConfig } from '../config' import { ObjectAdminDelete, ObjectCreatedCopyEvent, @@ -12,10 +16,7 @@ import { ObjectRemoved, ObjectRemovedMove, ObjectUpdatedMetadata, -} from '../queue' -import { randomUUID } from 'crypto' -import { ERRORS } from './errors' -import { getJwtSecret } from '../database/tenant' +} from './events' export interface UploadObjectOptions { objectName: string diff --git a/src/storage/protocols/s3/byte-limit-stream.ts b/src/storage/protocols/s3/byte-limit-stream.ts index c14008c3..fce7c98a 100644 --- a/src/storage/protocols/s3/byte-limit-stream.ts +++ b/src/storage/protocols/s3/byte-limit-stream.ts @@ -1,5 +1,5 @@ import { Transform, TransformCallback } from 'stream' -import { ERRORS } from '../../errors' +import { ERRORS } from '@internal/errors' export class ByteLimitTransformStream extends Transform { bytesProcessed = 0 diff --git a/src/storage/protocols/s3/s3-handler.ts b/src/storage/protocols/s3/s3-handler.ts index 3cc50977..82c3e84d 100644 --- a/src/storage/protocols/s3/s3-handler.ts +++ b/src/storage/protocols/s3/s3-handler.ts @@ -23,9 +23,9 @@ import { import { PassThrough, Readable } from 'stream' import stream from 'stream/promises' import { getFileSizeLimit, mustBeValidBucketName, mustBeValidKey } from '../../limits' -import { ERRORS } from '../../errors' +import { ERRORS } from '@internal/errors' import { S3MultipartUpload, Obj } from '../../schemas' -import { decrypt, encrypt } from '../../../auth' +import { decrypt, encrypt } from '@internal/auth' import { ByteLimitTransformStream } from './byte-limit-stream' const { storageS3Region, storageS3Bucket } = getConfig() diff --git a/src/storage/protocols/s3/signature-v4.ts b/src/storage/protocols/s3/signature-v4.ts index d65c92e2..30502bc5 100644 --- a/src/storage/protocols/s3/signature-v4.ts +++ b/src/storage/protocols/s3/signature-v4.ts @@ -1,5 +1,5 @@ import crypto from 'crypto' -import { ERRORS } from '../../errors' +import { ERRORS } from '@internal/errors' interface SignatureV4Options { enforceRegion: boolean @@ -24,7 +24,6 @@ interface SignatureRequest { method: string query?: Record prefix?: string - clientSignature: ClientSignature } interface Credentials { @@ -176,13 +175,25 @@ export class SignatureV4 { }, new Map()) } - verify(request: SignatureRequest) { - const { clientSignature, serverSignature } = this.sign(request) - return crypto.timingSafeEqual(Buffer.from(clientSignature), Buffer.from(serverSignature)) + /** + * Verify if client signature and server signature matches + * @param clientSignature + * @param request + */ + verify(clientSignature: ClientSignature, request: SignatureRequest) { + const serverSignature = this.sign(clientSignature, request) + return crypto.timingSafeEqual( + Buffer.from(clientSignature.signature), + Buffer.from(serverSignature) + ) } - sign(request: SignatureRequest) { - const clientSignature = request.clientSignature + /** + * Sign the server side signature + * @param clientSignature + * @param request + */ + sign(clientSignature: ClientSignature, request: SignatureRequest) { const serverCredentials = this.serverCredentials this.validateCredentials(clientSignature.credentials) @@ -193,7 +204,11 @@ export class SignatureV4 { } const selectedRegion = this.getSelectedRegion(clientSignature.credentials.region) - const canonicalRequest = this.constructCanonicalRequest(request, clientSignature.signedHeaders) + const canonicalRequest = this.constructCanonicalRequest( + clientSignature, + request, + clientSignature.signedHeaders + ) const stringToSign = this.constructStringToSign( longDate, clientSignature.credentials.shortDate, @@ -208,13 +223,10 @@ export class SignatureV4 { serverCredentials.service ) - return { - clientSignature: clientSignature.signature, - serverSignature: this.hmac(signingKey, stringToSign).toString('hex'), - } + return this.hmac(signingKey, stringToSign).toString('hex') } - getPayloadHash(request: SignatureRequest) { + protected getPayloadHash(clientSignature: ClientSignature, request: SignatureRequest) { const body = request.body // For presigned URLs and GET requests, use UNSIGNED-PAYLOAD @@ -223,8 +235,8 @@ export class SignatureV4 { } // If contentSha is provided, use it - if (request.clientSignature.contentSha) { - return request.clientSignature.contentSha + if (clientSignature.contentSha) { + return clientSignature.contentSha } // If the body is undefined, use the hash of an empty string @@ -244,14 +256,18 @@ export class SignatureV4 { return 'UNSIGNED-PAYLOAD' } - protected constructCanonicalRequest(request: SignatureRequest, signedHeaders: string[]) { + protected constructCanonicalRequest( + clientSignature: ClientSignature, + request: SignatureRequest, + signedHeaders: string[] + ) { const method = request.method const canonicalUri = new URL(`http://localhost:8080${request.prefix || ''}${request.url}`) .pathname const canonicalQueryString = this.constructCanonicalQueryString(request.query || {}) const canonicalHeaders = this.constructCanonicalHeaders(request, signedHeaders) const signedHeadersString = signedHeaders.sort().join(';') - const payloadHash = this.getPayloadHash(request) + const payloadHash = this.getPayloadHash(clientSignature, request) return `${method}\n${canonicalUri}\n${canonicalQueryString}\n${canonicalHeaders}\n${signedHeadersString}\n${payloadHash}` } diff --git a/src/storage/protocols/tus/postgres-locker.ts b/src/storage/protocols/tus/postgres-locker.ts index 61e516c0..fac00567 100644 --- a/src/storage/protocols/tus/postgres-locker.ts +++ b/src/storage/protocols/tus/postgres-locker.ts @@ -2,9 +2,9 @@ import { Lock, Locker, RequestRelease } from '@tus/server' import { clearTimeout } from 'timers' import EventEmitter from 'events' import { Database, DBError } from '../../database' -import { PubSubAdapter } from '../../../pubsub' +import { PubSubAdapter } from '@internal/pubsub' import { UploadId } from './upload-id' -import { ERRORS } from '../../errors' +import { ERRORS } from '@internal/errors' const REQUEST_LOCK_RELEASE_MESSAGE = 'REQUEST_LOCK_RELEASE' diff --git a/src/storage/protocols/tus/server.ts b/src/storage/protocols/tus/server.ts index d3ba2289..ac0c010a 100644 --- a/src/storage/protocols/tus/server.ts +++ b/src/storage/protocols/tus/server.ts @@ -1,4 +1,4 @@ -import { CancellationContext, ERRORS, Server } from '@tus/server' +import { ERRORS, Server } from '@tus/server' import http from 'node:http' export class TusServer extends Server { diff --git a/src/storage/protocols/tus/upload-id.ts b/src/storage/protocols/tus/upload-id.ts index 645d8ea7..a53d6382 100644 --- a/src/storage/protocols/tus/upload-id.ts +++ b/src/storage/protocols/tus/upload-id.ts @@ -1,5 +1,5 @@ import { getConfig } from '../../../config' -import { ERRORS } from '../../errors' +import { ERRORS } from '@internal/errors' import { mustBeValidBucketName, mustBeValidKey } from '../../limits' import { FILE_VERSION_SEPARATOR, PATH_SEPARATOR, SEPARATOR } from '../../backend' diff --git a/src/storage/renderer/image.ts b/src/storage/renderer/image.ts index 74b049a8..5b60229f 100644 --- a/src/storage/renderer/image.ts +++ b/src/storage/renderer/image.ts @@ -4,7 +4,7 @@ import { getConfig } from '../../config' import { FastifyRequest } from 'fastify' import { Renderer, RenderOptions } from './renderer' import axiosRetry from 'axios-retry' -import { ERRORS } from '../errors' +import { ERRORS } from '@internal/errors' import { Stream } from 'stream' import Agent from 'agentkeepalive' diff --git a/src/storage/storage.ts b/src/storage/storage.ts index d07178ce..54d2b7d0 100644 --- a/src/storage/storage.ts +++ b/src/storage/storage.ts @@ -1,6 +1,6 @@ import { StorageBackendAdapter, withOptionalVersion } from './backend' import { Database, FindBucketFilters } from './database' -import { ERRORS } from './errors' +import { ERRORS } from '@internal/errors' import { AssetRenderer, HeadRenderer, ImageRenderer } from './renderer' import { getFileSizeLimit, mustBeValidBucketName, parseFileSizeToBytes } from './limits' import { getConfig } from '../config' diff --git a/src/storage/uploader.ts b/src/storage/uploader.ts index 2f9c7d86..bc23107d 100644 --- a/src/storage/uploader.ts +++ b/src/storage/uploader.ts @@ -1,12 +1,14 @@ +import { randomUUID } from 'crypto' import { FastifyRequest } from 'fastify' -import { getFileSizeLimit } from './limits' + +import { ERRORS } from '@internal/errors' +import { FileUploadedSuccess, FileUploadStarted } from '@internal/monitoring/metrics' + import { ObjectMetadata, StorageBackendAdapter } from './backend' -import { getConfig } from '../config' -import { ERRORS } from './errors' +import { getFileSizeLimit } from './limits' import { Database } from './database' -import { ObjectAdminDelete, ObjectCreatedPostEvent, ObjectCreatedPutEvent } from '../queue' -import { randomUUID } from 'crypto' -import { FileUploadedSuccess, FileUploadStarted } from '../monitoring/metrics' +import { ObjectAdminDelete, ObjectCreatedPostEvent, ObjectCreatedPutEvent } from './events' +import { getConfig } from '../config' interface UploaderOptions extends UploadObjectOptions { fileSizeLimit?: number | null diff --git a/src/test/common.ts b/src/test/common.ts index 87749d1a..013193b8 100644 --- a/src/test/common.ts +++ b/src/test/common.ts @@ -1,8 +1,8 @@ +import { HeadBucketCommand, S3Client } from '@aws-sdk/client-s3' import app from '../admin-app' import { S3Backend } from '../storage/backend' -import { Queue } from '../queue' -import { HeadBucketCommand, S3Client } from '@aws-sdk/client-s3' -import { isS3Error } from '../storage' +import { Queue } from '@internal/queue' +import { isS3Error } from '@internal/errors' export const adminApp = app({}) diff --git a/src/test/generic-routes.test.ts b/src/test/generic-routes.test.ts index 75024128..4d579aaf 100644 --- a/src/test/generic-routes.test.ts +++ b/src/test/generic-routes.test.ts @@ -1,6 +1,6 @@ 'use strict' -import { createDefaultSchema, createResponse } from '../http/generic-routes' +import { createDefaultSchema, createResponse } from '../http/routes-helper' describe('testing Generic Routes Utils', () => { describe('creating generic responses [createResponse]', () => { diff --git a/src/test/jwt.test.ts b/src/test/jwt.test.ts index b8df575e..216666b9 100644 --- a/src/test/jwt.test.ts +++ b/src/test/jwt.test.ts @@ -1,6 +1,6 @@ import * as crypto from 'crypto' -import { verifyJWT } from '../auth' +import { verifyJWT } from '../internal/auth' describe('JWT', () => { describe('verifyJWT with JWKS', () => { diff --git a/src/test/object.test.ts b/src/test/object.test.ts index 40fc0db0..5fde5cff 100644 --- a/src/test/object.test.ts +++ b/src/test/object.test.ts @@ -4,17 +4,16 @@ import FormData from 'form-data' import fs from 'fs' import app from '../app' import { getConfig, mergeConfig } from '../config' -import { S3Backend } from '../storage/backend' -import { Obj } from '../storage/schemas' -import { signJWT } from '../auth' -import { ErrorCode, StorageBackendError } from '../storage' +import { signJWT } from '@internal/auth' +import { Obj, backends } from '../storage' import { useMockObject, useMockQueue } from './common' -import { getPostgresConnection } from '../database' -import { getServiceKeyUser } from '../database/tenant' +import { getServiceKeyUser, getPostgresConnection } from '@internal/database' import { Knex } from 'knex' +import { ErrorCode, StorageBackendError } from '@internal/errors' const { jwtSecret, serviceKey, tenantId } = getConfig() const anonKey = process.env.ANON_KEY || '' +const S3Backend = backends.S3Backend let tnx: Knex.Transaction | undefined async function getSuperuserPostgrestClient() { diff --git a/src/test/rls.test.ts b/src/test/rls.test.ts index 016cac1d..6702404d 100644 --- a/src/test/rls.test.ts +++ b/src/test/rls.test.ts @@ -6,15 +6,15 @@ import { getConfig } from '../config' import { checkBucketExists } from './common' import { createStorageBackend } from '../storage/backend' import { Knex, knex } from 'knex' -import { signJWT } from '../auth' +import { signJWT } from '../internal/auth' import fs from 'fs' import path from 'path' import { Storage } from '../storage' -import { getPostgresConnection } from '../database' +import { getPostgresConnection } from '../internal/database' import FormData from 'form-data' import yaml from 'js-yaml' import Mustache from 'mustache' -import { getServiceKeyUser } from '../database/tenant' +import { getServiceKeyUser } from '../internal/database/tenant' interface Policy { name: string diff --git a/src/test/tenant.test.ts b/src/test/tenant.test.ts index 64ac38a6..d47a8e92 100644 --- a/src/test/tenant.test.ts +++ b/src/test/tenant.test.ts @@ -1,7 +1,7 @@ 'use strict' import dotenv from 'dotenv' -import * as migrate from '../database/migrations/migrate' -import { multitenantKnex } from '../database/multitenant-db' +import * as migrate from '../internal/database/migrations/migrate' +import { multitenantKnex } from '../internal/database/multitenant-db' import { adminApp } from './common' dotenv.config({ path: '.env.test' }) diff --git a/src/test/tus.test.ts b/src/test/tus.test.ts index 5c78f1ee..dc54d48d 100644 --- a/src/test/tus.test.ts +++ b/src/test/tus.test.ts @@ -2,27 +2,25 @@ import dotenv from 'dotenv' import path from 'path' dotenv.config({ path: path.resolve(__dirname, '..', '..', '.env.test') }) -import { getPostgresConnection } from '../database' -import { getConfig } from '../config' -import { StorageKnexDB } from '../storage/database' -import { randomUUID } from 'crypto' -import * as tus from 'tus-js-client' import fs from 'fs' -import app from '../app' import { FastifyInstance } from 'fastify' -import { isS3Error, Storage } from '../storage' -import { createStorageBackend } from '../storage/backend' -import { CreateBucketCommand, S3Client } from '@aws-sdk/client-s3' -import { logger } from '../monitoring' +import { randomUUID } from 'crypto' +import * as tus from 'tus-js-client' import { DetailedError } from 'tus-js-client' -import { getServiceKeyUser } from '../database/tenant' +import { CreateBucketCommand, S3Client } from '@aws-sdk/client-s3' + +import { logger } from '@internal/monitoring' +import { getServiceKeyUser, getPostgresConnection } from '@internal/database' +import { getConfig } from '../config' +import app from '../app' import { checkBucketExists } from './common' +import { Storage, backends, StorageKnexDB } from '../storage' const { serviceKey, tenantId, storageS3Bucket, storageBackendType } = getConfig() const oneChunkFile = fs.createReadStream(path.resolve(__dirname, 'assets', 'sadcat.jpg')) const localServerAddress = 'http://127.0.0.1:8999' -const backend = createStorageBackend(storageBackendType) +const backend = backends.createStorageBackend(storageBackendType) const client = backend.client describe('Tus multipart', () => { diff --git a/src/test/webhooks.test.ts b/src/test/webhooks.test.ts index 62f9ad10..805565e0 100644 --- a/src/test/webhooks.test.ts +++ b/src/test/webhooks.test.ts @@ -1,4 +1,4 @@ -import { TenantConnection } from '../database/connection' +import { TenantConnection } from '../internal/database/connection' import { getConfig, mergeConfig } from '../config' const { serviceKey, tenantId } = getConfig() @@ -12,10 +12,10 @@ import FormData from 'form-data' import fs from 'fs' import app from '../app' -import { getPostgresConnection } from '../database' +import { getPostgresConnection } from '../internal/database' import { Obj } from '../storage/schemas' import { randomUUID } from 'crypto' -import { getServiceKeyUser } from '../database/tenant' +import { getServiceKeyUser } from '../internal/database/tenant' describe('Webhooks', () => { useMockObject() diff --git a/src/test/x-forwarded-host.test.ts b/src/test/x-forwarded-host.test.ts index 2091fac6..7956b468 100644 --- a/src/test/x-forwarded-host.test.ts +++ b/src/test/x-forwarded-host.test.ts @@ -1,9 +1,9 @@ 'use strict' import { adminApp } from './common' -import * as migrate from '../database/migrations/migrate' -import { multitenantKnex } from '../database/multitenant-db' +import * as migrate from '../internal/database/migrations/migrate' +import { multitenantKnex } from '../internal/database/multitenant-db' import app from '../app' -import * as tenant from '../database/tenant' +import * as tenant from '../internal/database/tenant' import { getConfig, mergeConfig } from '../config' beforeAll(async () => { diff --git a/src/worker.ts b/src/worker.ts index cf233159..9ae0a342 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1,12 +1,18 @@ -import { Queue } from './queue' -import { logger, logSchema } from './monitoring' -import adminApp from './admin-app' +import { Queue } from '@internal/queue' +import { logger, logSchema } from '@internal/monitoring' +import { registerWorkers } from '@storage/events' import { getConfig } from './config' +import adminApp from './admin-app' +/** + * Starts Storage Worker + */ export async function main() { const { requestTraceHeader, adminPort, host } = getConfig() logger.info('[Queue] Starting Queue Worker') + registerWorkers() + const queue = await Queue.init() const server = adminApp({ diff --git a/tsconfig.json b/tsconfig.json index aa826ff8..78433b52 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,9 @@ { "compilerOptions": { + "paths": { + "@internal/*": ["./src/internal/*"], + "@storage/*": ["./src/storage/*"], + }, "downlevelIteration": true, "emitDecoratorMetadata": true, "experimentalDecorators": true,