seahaven-ap/packages/api/src/documents.ts

77 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`;
},
};
}