@edgestore/server
Version:
Upload files with ease from React/Next.js
108 lines (105 loc) • 4.22 kB
JavaScript
import { S3Client, HeadObjectCommand, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { v4 } from 'uuid';
import { g as getEnv } from '../../shared-c6527780.mjs';
import '@edgestore/shared';
import '@panva/hkdf';
import 'cookie';
import 'jose';
function AWSProvider(options) {
const { accessKeyId = getEnv('ES_AWS_ACCESS_KEY_ID'), secretAccessKey = getEnv('ES_AWS_SECRET_ACCESS_KEY'), region = getEnv('ES_AWS_REGION'), bucketName = getEnv('ES_AWS_BUCKET_NAME'), endpoint = getEnv('ES_AWS_ENDPOINT'), forcePathStyle = getEnv('ES_AWS_FORCE_PATH_STYLE') === 'true', overwritePath } = options ?? {};
const baseUrl = options?.baseUrl ?? getEnv('EDGE_STORE_BASE_URL') ?? (endpoint ? `${endpoint}/${bucketName}` : `https://${bucketName}.s3.${region}.amazonaws.com`);
const credentials = accessKeyId && secretAccessKey ? {
accessKeyId,
secretAccessKey
} : undefined;
const s3Client = new S3Client({
region,
credentials,
endpoint,
forcePathStyle
});
return {
name: 'aws',
async init () {
return {};
},
getBaseUrl () {
return baseUrl;
},
async getFile ({ url }) {
const path = url.replace(`${baseUrl}/`, '');
const { ContentLength, LastModified } = await s3Client.send(new HeadObjectCommand({
Bucket: bucketName,
Key: path
}));
if (!ContentLength || !LastModified) {
throw new Error('File not found');
}
return {
url,
metadata: {},
path: {},
size: ContentLength,
uploadedAt: LastModified
};
},
async requestUpload (params) {
const { bucketName: esBucketName, fileInfo } = params;
if (!bucketName) {
throw new Error('S3 bucketName is not configured in AWSProviderOptions.');
}
// Default S3 key (accessPath) construction logic
const pathPrefix = `${esBucketName}${fileInfo.isPublic ? '/_public' : ''}`;
const nameId = v4();
const extension = fileInfo.extension ? `.${fileInfo.extension.replace('.', '')}` : '';
const defaultResolvedFileName = fileInfo.fileName ?? `${nameId}${extension}`;
const defaultFilePathFromMetadata = fileInfo.path.reduce((acc, item)=>{
return `${acc}/${item.value}`;
}, '');
let accessPath = `${pathPrefix}${defaultFilePathFromMetadata}/${defaultResolvedFileName}`;
if (overwritePath) {
accessPath = await overwritePath({
esBucketName,
fileInfo,
defaultAccessPath: accessPath
});
}
const command = new PutObjectCommand({
Bucket: bucketName,
Key: accessPath
});
const signedUrl = await getSignedUrl(s3Client, command, {
expiresIn: 60 * 60
});
const finalAccessUrl = `${baseUrl}/${accessPath.startsWith('/') ? accessPath.substring(1) : accessPath}`;
return {
uploadUrl: signedUrl,
accessUrl: finalAccessUrl
};
},
async requestUploadParts () {
throw new Error('Not implemented');
},
async completeMultipartUpload () {
throw new Error('Not implemented');
},
async confirmUpload () {
throw new Error('Not implemented');
},
async deleteFile ({ url }) {
if (!bucketName) {
throw new Error('S3 bucketName is not configured in AWSProviderOptions for deleteFile.');
}
const path = url.replace(`${baseUrl}/`, '');
await s3Client.send(new DeleteObjectCommand({
Bucket: bucketName,
Key: path
}));
return {
success: true
};
}
};
}
export { AWSProvider };