feat(storage): storage port and minio adapter with forbid-overwrite semantics

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-17 20:25:18 +08:00
parent 59464bd73d
commit 37f4b3e11f
10 changed files with 748 additions and 3 deletions
+346 -3
View File
@@ -46,7 +46,7 @@ importers:
version: 7.13.0(typescript@5.9.3)
ts-jest:
specifier: ^29.2.0
version: 29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0)(typescript@5.9.3)
version: 29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.20.3)(ts-node@10.9.2(@types/node@22.20.3)(typescript@5.9.3)))(typescript@5.9.3)
typescript:
specifier: ^5.6.0
version: 5.9.3
@@ -64,6 +64,37 @@ importers:
specifier: ^5.6.0
version: 5.9.3
packages/storage:
dependencies:
'@aws-sdk/client-s3':
specifier: ^3.700.0
version: 3.1134.0
'@aws-sdk/s3-request-presigner':
specifier: ^3.700.0
version: 3.1134.0
'@photo/contracts':
specifier: workspace:*
version: link:../contracts
devDependencies:
'@types/jest':
specifier: ^29.5.13
version: 29.5.14
'@types/node':
specifier: ^22.10.0
version: 22.20.3
dotenv:
specifier: ^16.4.5
version: 16.6.1
jest:
specifier: ^29.7.0
version: 29.7.0(@types/node@22.20.3)(ts-node@10.9.2(@types/node@22.20.3)(typescript@5.9.3))
ts-jest:
specifier: ^29.2.5
version: 29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.20.3)(ts-node@10.9.2(@types/node@22.20.3)(typescript@5.9.3)))(typescript@5.9.3)
typescript:
specifier: ^5.6.0
version: 5.9.3
services/api:
dependencies:
'@nestjs/common':
@@ -120,7 +151,7 @@ importers:
version: 7.2.2
ts-jest:
specifier: ^29.2.5
version: 29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0)(typescript@5.9.3)
version: 29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.20.3)(ts-node@10.9.2(@types/node@22.20.3)(typescript@5.9.3)))(typescript@5.9.3)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@22.20.3)(typescript@5.9.3)
@@ -130,6 +161,82 @@ importers:
packages:
'@aws-sdk/checksums@3.1001.0':
resolution: {integrity: sha512-6uTniZc87q+B5eXouGTl+7Tmc482rEeCcvxpsvREP8EfF0gvloRZ41UOA9sbSJlyy8TbqIBXb3kKfKarEArUQA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/client-s3@3.1134.0':
resolution: {integrity: sha512-dHgbuWMkladVNpR5gEQ7K9ub20w/hcf9IJXtMr+S3/rYpr6Z4gWUEX1seAPj00nAxJqtAaYvX3wdr2BVukZXXQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/core@3.978.0':
resolution: {integrity: sha512-2yX9LUmxPklVjSGTb8dfnWRJSiFQ3TeH2nn7G1mdKHTfnabzF0+gfrS8rYfLWmZrQ8A3mEcxMJjRc51dL5KWaA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-env@3.972.71':
resolution: {integrity: sha512-JN+JHruYZw3GUZB8YGAlDk4wTDPOEAEEdEzj5nS0xodWR4smzHsN7PnK2j6IeOsDIj2aqua5DSbhXl9Gtf90FQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-http@3.972.73':
resolution: {integrity: sha512-uyYYnJOnlis8uQzaYGPd7N1JoioCoNpXgnkXYixsWJXHXgXyYi8WXJSDfofxJeWfQIGWLe2Nwyq60Uc7MZdVOg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-ini@3.973.16':
resolution: {integrity: sha512-i++ly+0Uxa+u3ebSSyr0S/3CFhFJDxCXT3+Zj+mW2bXenEx5bKGCdTIKFu39SgXBNhWDjex/8cXUx9MUTMCrTw==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-login@3.972.78':
resolution: {integrity: sha512-eUtswnXu0+Ii9ieRK+0L7aPFV3Z/dnW2VntJzjBP9xs8s+8p5nBNuymIXtXwZ+5r5+XJP3e32nMkuZ/r0HozEA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-node@3.972.83':
resolution: {integrity: sha512-jdso7ejzfRnatxMUZK4S/U6KbaDPCvfIV4XL+IQAPFDBt5rj5Fq595euqlK8Le4lNCMFR9oUpt+1l0aMgaayOQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-process@3.972.71':
resolution: {integrity: sha512-lYmXJa4gvq4xN1lrT5NiP5vIYYKcGWAdj8y+8o6dlcateB5eF3Dn8DtmjjHKfMBrTPAMr2pebIiX/UOj8c1/UA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-sso@3.973.15':
resolution: {integrity: sha512-6Jhcf4v0pSFdjk1EW2kvzuEBKD+UZ2uNcHUIglKKLndD20YhvkL2kdmDOV5/j4mYuWWwe/a1FQ1aomU86/Cg5Q==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-web-identity@3.972.77':
resolution: {integrity: sha512-uylIQSUWpfLuH2LovxEEfwzJGM/SabLOfLMg6YXu/E8jJEKUdpdILCVCQCdFvHyu/7dLJOHPMfrSwduxO56NkQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-sdk-s3@3.972.76':
resolution: {integrity: sha512-NfnTkVUTBKTBuBgqaapFK9r3YdkKt1b2oRvgLzZq91bwNKh6ZS0S7sEcheguttREaL4iyfs/xQnqD7Z7AsWSsA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/nested-clients@3.997.45':
resolution: {integrity: sha512-mooq9Q+jLa18VoM7HouczmslZU60iiB0aKc/Ztnq/luIL1ud0z4DnYprLR/ZO1gp331S9tJctM1HZr7u6YKBXQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/s3-request-presigner@3.1134.0':
resolution: {integrity: sha512-75DC3biOXXmSWqCN2hwJmhMPjDdgc1twjNJEknuWhY9M/E9eFIQufXkwOQx5raNTg6P/FbCgk9tp4y2SZ7vZFA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/signature-v4-multi-region@3.996.46':
resolution: {integrity: sha512-L+2xZTye/2T96f3lwCws0Zw6GG2JHZW9e8FpVgGBeeExSKyeoZ6CWRpBml/7DNiK/O26jrgPM9F+Ay8VkgzUWQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/token-providers@3.1129.0':
resolution: {integrity: sha512-Sbl3rpzQdsG4ZK2zh0JWUYyZPKKorJlVOddA2T0DVbKJFrsW8J6wgnslxxUH04+WaBMr4A1HzJZvZX0xUvkniA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/types@3.974.5':
resolution: {integrity: sha512-LkwLL2BLbC6wNNm4JaH9mbEqBMdOZCct6VAYqhdN4U1xrWM+fUJQEfbHwQgDypapOWTRtlk25akb5afM0P8CIQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/xml-builder@3.972.40':
resolution: {integrity: sha512-wlFmCIGUlwF4zx/kncw+bmxTQh1HeSJq4mYV/V5cZUSJadDP3kXvGW8Rn21cimj/7y9ju+47oYWXi97vF7czaA==}
engines: {node: '>=20.0.0'}
'@aws/lambda-invoke-store@0.3.0':
resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==}
engines: {node: '>=18.0.0'}
'@babel/code-frame@7.29.7':
resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
engines: {node: '>=6.9.0'}
@@ -691,6 +798,30 @@ packages:
'@sinonjs/fake-timers@10.3.0':
resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==}
'@smithy/core@3.34.1':
resolution: {integrity: sha512-dLcOUxz8YCv1RZUMKq6GbyUf95pLbrqh34bPvpCZ1+CByFF31BEAFewZjsGCnVsZTKdThNENfGyAgk2TJqVwSw==}
engines: {node: '>=18.0.0'}
'@smithy/credential-provider-imds@4.5.2':
resolution: {integrity: sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==}
engines: {node: '>=18.0.0'}
'@smithy/fetch-http-handler@5.8.0':
resolution: {integrity: sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA==}
engines: {node: '>=18.0.0'}
'@smithy/node-http-handler@4.12.1':
resolution: {integrity: sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw==}
engines: {node: '>=18.0.0'}
'@smithy/signature-v4@5.7.3':
resolution: {integrity: sha512-7ImGm+FkHRLcBaRttIAMZ6bzJZWb2cJGoYjq46F2UjycujWzrL9GEN9h4w7eQyXJYnltrUhxbbieBAIRrdqpow==}
engines: {node: '>=18.0.0'}
'@smithy/types@4.18.0':
resolution: {integrity: sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A==}
engines: {node: '>=18.0.0'}
'@tokenizer/inflate@0.2.7':
resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==}
engines: {node: '>=18'}
@@ -991,6 +1122,9 @@ packages:
resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
bowser@2.14.1:
resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==}
brace-expansion@1.1.21:
resolution: {integrity: sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==}
@@ -2928,6 +3062,180 @@ packages:
snapshots:
'@aws-sdk/checksums@3.1001.0':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/client-s3@3.1134.0':
dependencies:
'@aws-sdk/checksums': 3.1001.0
'@aws-sdk/core': 3.978.0
'@aws-sdk/credential-provider-node': 3.972.83
'@aws-sdk/middleware-sdk-s3': 3.972.76
'@aws-sdk/signature-v4-multi-region': 3.996.46
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/fetch-http-handler': 5.8.0
'@smithy/node-http-handler': 4.12.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/core@3.978.0':
dependencies:
'@aws-sdk/types': 3.974.5
'@aws-sdk/xml-builder': 3.972.40
'@aws/lambda-invoke-store': 0.3.0
'@smithy/core': 3.34.1
'@smithy/signature-v4': 5.7.3
'@smithy/types': 4.18.0
bowser: 2.14.1
tslib: 2.8.1
'@aws-sdk/credential-provider-env@3.972.71':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/credential-provider-http@3.972.73':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/fetch-http-handler': 5.8.0
'@smithy/node-http-handler': 4.12.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/credential-provider-ini@3.973.16':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/credential-provider-env': 3.972.71
'@aws-sdk/credential-provider-http': 3.972.73
'@aws-sdk/credential-provider-login': 3.972.78
'@aws-sdk/credential-provider-process': 3.972.71
'@aws-sdk/credential-provider-sso': 3.973.15
'@aws-sdk/credential-provider-web-identity': 3.972.77
'@aws-sdk/nested-clients': 3.997.45
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/credential-provider-imds': 4.5.2
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/credential-provider-login@3.972.78':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/nested-clients': 3.997.45
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/credential-provider-node@3.972.83':
dependencies:
'@aws-sdk/credential-provider-env': 3.972.71
'@aws-sdk/credential-provider-http': 3.972.73
'@aws-sdk/credential-provider-ini': 3.973.16
'@aws-sdk/credential-provider-process': 3.972.71
'@aws-sdk/credential-provider-sso': 3.973.15
'@aws-sdk/credential-provider-web-identity': 3.972.77
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/credential-provider-imds': 4.5.2
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/credential-provider-process@3.972.71':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/credential-provider-sso@3.973.15':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/nested-clients': 3.997.45
'@aws-sdk/token-providers': 3.1129.0
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/credential-provider-web-identity@3.972.77':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/nested-clients': 3.997.45
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/middleware-sdk-s3@3.972.76':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/signature-v4-multi-region': 3.996.46
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/nested-clients@3.997.45':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/signature-v4-multi-region': 3.996.46
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/fetch-http-handler': 5.8.0
'@smithy/node-http-handler': 4.12.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/s3-request-presigner@3.1134.0':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/signature-v4-multi-region': 3.996.46
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/signature-v4-multi-region@3.996.46':
dependencies:
'@aws-sdk/types': 3.974.5
'@smithy/signature-v4': 5.7.3
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/token-providers@3.1129.0':
dependencies:
'@aws-sdk/core': 3.978.0
'@aws-sdk/nested-clients': 3.997.45
'@aws-sdk/types': 3.974.5
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/types@3.974.5':
dependencies:
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws-sdk/xml-builder@3.972.40':
dependencies:
'@smithy/types': 4.18.0
tslib: 2.8.1
'@aws/lambda-invoke-store@0.3.0': {}
'@babel/code-frame@7.29.7':
dependencies:
'@babel/helper-validator-identifier': 7.29.7
@@ -3675,6 +3983,39 @@ snapshots:
dependencies:
'@sinonjs/commons': 3.0.1
'@smithy/core@3.34.1':
dependencies:
'@smithy/types': 4.18.0
tslib: 2.8.1
'@smithy/credential-provider-imds@4.5.2':
dependencies:
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@smithy/fetch-http-handler@5.8.0':
dependencies:
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@smithy/node-http-handler@4.12.1':
dependencies:
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@smithy/signature-v4@5.7.3':
dependencies:
'@smithy/core': 3.34.1
'@smithy/types': 4.18.0
tslib: 2.8.1
'@smithy/types@4.18.0':
dependencies:
tslib: 2.8.1
'@tokenizer/inflate@0.2.7':
dependencies:
debug: 4.4.3(supports-color@10.2.2)
@@ -4033,6 +4374,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
bowser@2.14.1: {}
brace-expansion@1.1.21:
dependencies:
balanced-match: 1.0.2
@@ -5914,7 +6257,7 @@ snapshots:
dependencies:
typescript: 5.9.3
ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0)(typescript@5.9.3):
ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.20.3)(ts-node@10.9.2(@types/node@22.20.3)(typescript@5.9.3)))(typescript@5.9.3):
dependencies:
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0