turborepo-remote-cache
Version:
Turborepo remote cache server
93 lines • 7.58 kB
JavaScript
import { PassThrough, Writable } from 'node:stream';
import { Readable } from 'node:stream';
import { GetObjectCommand, HeadObjectCommand, S3Client, } from '@aws-sdk/client-s3';
import { Upload } from '@aws-sdk/lib-storage';
export function isCacheMissError(error) {
if (typeof error !== 'object' || error === null) {
return false;
}
const err = error;
const statusCode = err.$metadata?.httpStatusCode;
return (err.name === 'NotFound' ||
err.name === 'NoSuchKey' ||
err.Code === 'NoSuchKey' ||
statusCode === 404 ||
statusCode === 403);
}
export function createS3({ accessKey = process.env.S3_ACCESS_KEY, secretKey = process.env.S3_SECRET_KEY, bucket, region = process.env.S3_REGION, endpoint, maxSockets, s3OptionsPassthrough = {}, }) {
if (!bucket) {
throw new Error('S3 bucket is required; please set the STORAGE_PATH environment variable to the bucket name');
}
const client = new S3Client({
credentials: accessKey && secretKey
? {
accessKeyId: accessKey,
secretAccessKey: secretKey,
}
: undefined,
region,
endpoint,
...(maxSockets
? {
requestHandler: {
httpsAgent: { maxSockets },
},
}
: {}),
...(process.env.NODE_ENV === 'test'
? { sslEnabled: false, s3ForcePathStyle: true }
: {}),
...s3OptionsPassthrough,
});
return {
exists: async (key, cb) => {
try {
await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
return cb(null, true);
}
catch (error) {
if (isCacheMissError(error)) {
return cb(null, false);
}
return cb(error);
}
},
createReadStream: (key) => {
const passThrough = new PassThrough();
client
.send(new GetObjectCommand({ Bucket: bucket, Key: key }))
.then((data) => {
if (data.Body) {
if (data.Body instanceof Readable) {
data.Body.pipe(passThrough);
}
else {
const stream = Readable.from(data.Body);
stream.pipe(passThrough);
}
}
})
.catch((err) => passThrough.destroy(err));
return passThrough;
},
createWriteStream: (key) => {
const passThrough = new PassThrough();
const upload = new Upload({
client,
params: { Bucket: bucket, Key: key, Body: passThrough },
});
const uploadPromise = upload.done();
const writeStream = new Writable({
write(chunk, encoding, callback) {
passThrough.write(chunk, encoding, callback);
},
final(callback) {
passThrough.end();
uploadPromise.then(() => callback()).catch(callback);
},
});
return writeStream;
},
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiczMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcGx1Z2lucy9yZW1vdGUtY2FjaGUvc3RvcmFnZS9zMy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3RDLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLFFBQVEsR0FFVCxNQUFNLG9CQUFvQixDQUFBO0FBQzNCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQW1DN0MsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEtBQWM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ2hELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUNELE1BQU0sR0FBRyxHQUFHLEtBSVgsQ0FBQTtJQUNELE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFBO0lBQ2hELE9BQU8sQ0FDTCxHQUFHLENBQUMsSUFBSSxLQUFLLFVBQVU7UUFDdkIsR0FBRyxDQUFDLElBQUksS0FBSyxXQUFXO1FBQ3hCLEdBQUcsQ0FBQyxJQUFJLEtBQUssV0FBVztRQUN4QixVQUFVLEtBQUssR0FBRztRQUNsQixVQUFVLEtBQUssR0FBRyxDQUNuQixDQUFBO0FBQ0gsQ0FBQztBQUdELE1BQU0sVUFBVSxRQUFRLENBQUMsRUFDdkIsU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUNyQyxTQUFTLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQ3JDLE1BQU0sRUFDTixNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQzlCLFFBQVEsRUFDUixVQUFVLEVBQ1Ysb0JBQW9CLEdB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