fix: satisfy deploy lint gate for S3 compatibility work

- Apply Biome organize-import/formatting fixes across changed S3 files
- Replace remaining string concatenations with template literals for lint
- Make home page inline handlers explicit via window.* and add button types
- Clean S3 auth lint issues with dot-property access and optional chaining
- Keep GetObject proxy and production/S3 SDK tests passing

Verification:
- bun run lint (0 errors, 1 CSS specificity warning)
- S3_SECRET_KEY=<env> bun test test/production-e2e.test.ts (29 pass)
- S3_SECRET_KEY=<env> bun test test/s3-sdk.test.ts (20 pass)
- bun test test/s3-auth.test.ts (5 pass)
This commit is contained in:
asepharyana
2026-07-07 03:07:51 +07:00
parent 06f93e30f6
commit 9a48fbf227
14 changed files with 161 additions and 124 deletions
+29 -25
View File
@@ -16,25 +16,25 @@
* CAUTION: creates & destroys real resources on the production server!
*/
import { describe, expect, it, afterAll } from 'bun:test';
import { afterAll, describe, expect, it } from 'bun:test';
import {
S3Client,
ListBucketsCommand,
CreateBucketCommand,
HeadBucketCommand,
DeleteBucketCommand,
PutObjectCommand,
GetObjectCommand,
HeadObjectCommand,
ListObjectsV2Command,
ListObjectsCommand,
AbortMultipartUploadCommand,
CopyObjectCommand,
CreateBucketCommand,
DeleteBucketCommand,
DeleteObjectCommand,
DeleteObjectsCommand,
GetObjectCommand,
HeadBucketCommand,
HeadObjectCommand,
ListBucketsCommand,
ListMultipartUploadsCommand,
AbortMultipartUploadCommand,
ListObjectsCommand,
ListObjectsV2Command,
NoSuchKey,
NotFound,
PutObjectCommand,
S3Client,
} from '@aws-sdk/client-s3';
// ── Config ───────────────────────────────────────────────────────────────────
@@ -66,21 +66,29 @@ afterAll(async () => {
if (keys.length) {
await s3.send(new DeleteObjectsCommand({ Bucket: b, Delete: { Objects: keys } }));
}
} catch { /* best-effort */ }
} catch {
/* best-effort */
}
// Clean up any multipart uploads
try {
const { Uploads = [] } = await s3.send(
new ListMultipartUploadsCommand({ Bucket: b }),
);
const { Uploads = [] } = await s3.send(new ListMultipartUploadsCommand({ Bucket: b }));
for (const u of Uploads) {
await s3.send(
new AbortMultipartUploadCommand({
Bucket: b, Key: u.Key!, UploadId: u.UploadId!,
Bucket: b,
Key: u.Key!,
UploadId: u.UploadId!,
}),
);
}
} catch { /* best-effort */ }
try { await s3.send(new DeleteBucketCommand({ Bucket: b })); } catch { /* best-effort */ }
} catch {
/* best-effort */
}
try {
await s3.send(new DeleteBucketCommand({ Bucket: b }));
} catch {
/* best-effort */
}
}
});
@@ -234,9 +242,7 @@ describe('S3 SDK compatibility', () => {
it('DeleteObject removes a single object', async () => {
await s3.send(new DeleteObjectCommand({ Bucket: BUCKET, Key: 'folder/nested-file.txt' }));
// Verify deletion
const { Contents } = await s3.send(
new ListObjectsV2Command({ Bucket: BUCKET }),
);
const { Contents } = await s3.send(new ListObjectsV2Command({ Bucket: BUCKET }));
expect(Contents!.some((o) => o.Key === 'folder/nested-file.txt')).toBe(false);
});
@@ -255,9 +261,7 @@ describe('S3 SDK compatibility', () => {
expect(Deleted).toHaveLength(3);
expect(Errors).toBeUndefined();
// Verify all deleted
const { Contents } = await s3.send(
new ListObjectsV2Command({ Bucket: BUCKET }),
);
const { Contents } = await s3.send(new ListObjectsV2Command({ Bucket: BUCKET }));
for (const k of ['del-a.txt', 'del-b.txt', 'del-c.txt']) {
expect(Contents!.some((o) => o.Key === k)).toBe(false);
}