mirror of
https://github.com/Sea-Haven-Industries/seahaven-ap.git
synced 2026-10-03 02:13:14 +00:00
78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
|
|
import {
|
||
|
|
GetObjectCommand,
|
||
|
|
HeadObjectCommand,
|
||
|
|
PutObjectCommand,
|
||
|
|
S3Client,
|
||
|
|
} from "@aws-sdk/client-s3";
|
||
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
||
|
|
import type { ApiEnv } from "./env.js";
|
||
|
|
|
||
|
|
export type PresignPutResult = {
|
||
|
|
url: string;
|
||
|
|
headers: Record<string, string>;
|
||
|
|
};
|
||
|
|
|
||
|
|
export type DocumentsStore = {
|
||
|
|
presignPut(input: { objectKey: string; contentType: string }): Promise<PresignPutResult>;
|
||
|
|
objectExists(objectKey: string): Promise<boolean>;
|
||
|
|
presignGet(objectKey: string): Promise<string>;
|
||
|
|
};
|
||
|
|
|
||
|
|
const SIGN_EXPIRES_SECONDS = 900;
|
||
|
|
|
||
|
|
export function createDocumentsStore(env: ApiEnv): DocumentsStore {
|
||
|
|
const client = new S3Client({
|
||
|
|
region: env.awsRegion,
|
||
|
|
endpoint: env.documentsEndpoint || undefined,
|
||
|
|
forcePathStyle: Boolean(env.documentsEndpoint),
|
||
|
|
credentials:
|
||
|
|
env.documentsAccessKey && env.documentsSecretKey
|
||
|
|
? { accessKeyId: env.documentsAccessKey, secretAccessKey: env.documentsSecretKey }
|
||
|
|
: undefined,
|
||
|
|
});
|
||
|
|
const bucket = env.documentsBucket;
|
||
|
|
|
||
|
|
return {
|
||
|
|
async presignPut({ objectKey, contentType }) {
|
||
|
|
const url = await getSignedUrl(
|
||
|
|
client,
|
||
|
|
new PutObjectCommand({ Bucket: bucket, Key: objectKey, ContentType: contentType }),
|
||
|
|
{ expiresIn: SIGN_EXPIRES_SECONDS },
|
||
|
|
);
|
||
|
|
return { url, headers: { "Content-Type": contentType } };
|
||
|
|
},
|
||
|
|
async objectExists(objectKey) {
|
||
|
|
try {
|
||
|
|
await client.send(new HeadObjectCommand({ Bucket: bucket, Key: objectKey }));
|
||
|
|
return true;
|
||
|
|
} catch {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
},
|
||
|
|
async presignGet(objectKey) {
|
||
|
|
return getSignedUrl(client, new GetObjectCommand({ Bucket: bucket, Key: objectKey }), {
|
||
|
|
expiresIn: SIGN_EXPIRES_SECONDS,
|
||
|
|
});
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createMemoryDocumentsStore(): DocumentsStore & { uploaded: Set<string> } {
|
||
|
|
const uploaded = new Set<string>();
|
||
|
|
return {
|
||
|
|
uploaded,
|
||
|
|
async presignPut({ objectKey, contentType }) {
|
||
|
|
return {
|
||
|
|
url: `http://127.0.0.1:9000/seahaven-ap-documents/${objectKey}?presign=put`,
|
||
|
|
headers: { "Content-Type": contentType },
|
||
|
|
};
|
||
|
|
},
|
||
|
|
async objectExists(objectKey) {
|
||
|
|
return uploaded.has(objectKey);
|
||
|
|
},
|
||
|
|
async presignGet(objectKey) {
|
||
|
|
return `http://127.0.0.1:9000/seahaven-ap-documents/${objectKey}?presign=get`;
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|