Support runtime environment variables using server components. This will mean docker images can change env vars for runtime as required.
64 lines
1.5 KiB
TypeScript
64 lines
1.5 KiB
TypeScript
import { base64 } from '@scure/base';
|
|
import { match } from 'ts-pattern';
|
|
|
|
import { DocumentDataType } from '@documenso/prisma/client';
|
|
|
|
import { createDocumentData } from '../../server-only/document-data/create-document-data';
|
|
import { getRuntimeEnv } from '../runtime-env/get-runtime-env';
|
|
|
|
type File = {
|
|
name: string;
|
|
type: string;
|
|
arrayBuffer: () => Promise<ArrayBuffer>;
|
|
};
|
|
|
|
export const putFile = async (file: File) => {
|
|
const { NEXT_PUBLIC_UPLOAD_TRANSPORT } = getRuntimeEnv();
|
|
|
|
const { type, data } = await match(NEXT_PUBLIC_UPLOAD_TRANSPORT)
|
|
.with('s3', async () => putFileInS3(file))
|
|
.otherwise(async () => putFileInDatabase(file));
|
|
|
|
return await createDocumentData({ type, data });
|
|
};
|
|
|
|
const putFileInDatabase = async (file: File) => {
|
|
const contents = await file.arrayBuffer();
|
|
|
|
const binaryData = new Uint8Array(contents);
|
|
|
|
const asciiData = base64.encode(binaryData);
|
|
|
|
return {
|
|
type: DocumentDataType.BYTES_64,
|
|
data: asciiData,
|
|
};
|
|
};
|
|
|
|
const putFileInS3 = async (file: File) => {
|
|
const { getPresignPostUrl } = await import('./server-actions');
|
|
|
|
const { url, key } = await getPresignPostUrl(file.name, file.type);
|
|
|
|
const body = await file.arrayBuffer();
|
|
|
|
const reponse = await fetch(url, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/octet-stream',
|
|
},
|
|
body,
|
|
});
|
|
|
|
if (!reponse.ok) {
|
|
throw new Error(
|
|
`Failed to upload file "${file.name}", failed with status code ${reponse.status}`,
|
|
);
|
|
}
|
|
|
|
return {
|
|
type: DocumentDataType.S3_PATH,
|
|
data: key,
|
|
};
|
|
};
|