mirror of https://github.com/actions/cache
dist
This commit is contained in:
parent
e477012777
commit
8f9e839eda
|
|
@ -25009,6 +25009,481 @@ const client_sts_1 = __nccwpck_require__(2209);
|
||||||
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3087:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
Upload: () => Upload
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var import_client_s3 = __nccwpck_require__(9250);
|
||||||
|
var import_abort_controller = __nccwpck_require__(7020);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_smithy_client = __nccwpck_require__(3570);
|
||||||
|
var import_events = __nccwpck_require__(2361);
|
||||||
|
|
||||||
|
// src/bytelength.ts
|
||||||
|
var import_runtimeConfig = __nccwpck_require__(3407);
|
||||||
|
var byteLength = /* @__PURE__ */ __name((input) => {
|
||||||
|
if (input === null || input === void 0)
|
||||||
|
return 0;
|
||||||
|
if (typeof input === "string")
|
||||||
|
input = Buffer.from(input);
|
||||||
|
if (typeof input.byteLength === "number") {
|
||||||
|
return input.byteLength;
|
||||||
|
} else if (typeof input.length === "number") {
|
||||||
|
return input.length;
|
||||||
|
} else if (typeof input.size === "number") {
|
||||||
|
return input.size;
|
||||||
|
} else if (typeof input.path === "string") {
|
||||||
|
try {
|
||||||
|
return import_runtimeConfig.ClientDefaultValues.lstatSync(input.path).size;
|
||||||
|
} catch (error) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return void 0;
|
||||||
|
}, "byteLength");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
|
||||||
|
var import_stream = __nccwpck_require__(2781);
|
||||||
|
|
||||||
|
// src/chunks/getChunkBuffer.ts
|
||||||
|
async function* getChunkBuffer(data, partSize) {
|
||||||
|
let partNumber = 1;
|
||||||
|
let startByte = 0;
|
||||||
|
let endByte = partSize;
|
||||||
|
while (endByte < data.byteLength) {
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte, endByte)
|
||||||
|
};
|
||||||
|
partNumber += 1;
|
||||||
|
startByte = endByte;
|
||||||
|
endByte = startByte + partSize;
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkBuffer, "getChunkBuffer");
|
||||||
|
|
||||||
|
// src/chunks/getChunkStream.ts
|
||||||
|
var import_buffer = __nccwpck_require__(4300);
|
||||||
|
async function* getChunkStream(data, partSize, getNextData) {
|
||||||
|
let partNumber = 1;
|
||||||
|
const currentBuffer = { chunks: [], length: 0 };
|
||||||
|
for await (const datum of getNextData(data)) {
|
||||||
|
currentBuffer.chunks.push(datum);
|
||||||
|
currentBuffer.length += datum.length;
|
||||||
|
while (currentBuffer.length >= partSize) {
|
||||||
|
const dataChunk = currentBuffer.chunks.length > 1 ? import_buffer.Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0];
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: dataChunk.slice(0, partSize)
|
||||||
|
};
|
||||||
|
currentBuffer.chunks = [dataChunk.slice(partSize)];
|
||||||
|
currentBuffer.length = currentBuffer.chunks[0].length;
|
||||||
|
partNumber += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: import_buffer.Buffer.concat(currentBuffer.chunks),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkStream, "getChunkStream");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadable.ts
|
||||||
|
|
||||||
|
async function* getDataReadable(data) {
|
||||||
|
for await (const chunk of data) {
|
||||||
|
yield import_buffer.Buffer.from(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadable, "getDataReadable");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadableStream.ts
|
||||||
|
|
||||||
|
async function* getDataReadableStream(data) {
|
||||||
|
const reader = data.getReader();
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done)
|
||||||
|
return;
|
||||||
|
yield import_buffer.Buffer.from(value);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
reader.releaseLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadableStream, "getDataReadableStream");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
var getChunk = /* @__PURE__ */ __name((data, partSize) => {
|
||||||
|
if (data instanceof import_buffer.Buffer) {
|
||||||
|
return getChunkBuffer(data, partSize);
|
||||||
|
} else if (data instanceof import_stream.Readable) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadable);
|
||||||
|
} else if (data instanceof String || typeof data === "string" || data instanceof Uint8Array) {
|
||||||
|
return getChunkBuffer(import_buffer.Buffer.from(data), partSize);
|
||||||
|
}
|
||||||
|
if (typeof data.stream === "function") {
|
||||||
|
return getChunkStream(data.stream(), partSize, getDataReadableStream);
|
||||||
|
} else if (data instanceof ReadableStream) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadableStream);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
"Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, "getChunk");
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var MIN_PART_SIZE = 1024 * 1024 * 5;
|
||||||
|
var _Upload = class _Upload extends import_events.EventEmitter {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
/**
|
||||||
|
* S3 multipart upload does not allow more than 10000 parts.
|
||||||
|
*/
|
||||||
|
this.MAX_PARTS = 1e4;
|
||||||
|
// Defaults.
|
||||||
|
this.queueSize = 4;
|
||||||
|
this.partSize = MIN_PART_SIZE;
|
||||||
|
this.leavePartsOnError = false;
|
||||||
|
this.tags = [];
|
||||||
|
this.concurrentUploaders = [];
|
||||||
|
this.uploadedParts = [];
|
||||||
|
this.isMultiPart = true;
|
||||||
|
this.queueSize = options.queueSize || this.queueSize;
|
||||||
|
this.partSize = options.partSize || this.partSize;
|
||||||
|
this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
|
||||||
|
this.tags = options.tags || this.tags;
|
||||||
|
this.client = options.client;
|
||||||
|
this.params = options.params;
|
||||||
|
this.__validateInput();
|
||||||
|
this.totalBytes = byteLength(this.params.Body);
|
||||||
|
this.bytesUploadedSoFar = 0;
|
||||||
|
this.abortController = options.abortController ?? new import_abort_controller.AbortController();
|
||||||
|
}
|
||||||
|
async abort() {
|
||||||
|
this.abortController.abort();
|
||||||
|
}
|
||||||
|
async done() {
|
||||||
|
return await Promise.race([this.__doMultipartUpload(), this.__abortTimeout(this.abortController.signal)]);
|
||||||
|
}
|
||||||
|
on(event, listener) {
|
||||||
|
this.uploadEvent = event;
|
||||||
|
return super.on(event, listener);
|
||||||
|
}
|
||||||
|
async __uploadUsingPut(dataPart) {
|
||||||
|
var _a;
|
||||||
|
this.isMultiPart = false;
|
||||||
|
const params = { ...this.params, Body: dataPart.data };
|
||||||
|
const clientConfig = this.client.config;
|
||||||
|
const requestHandler = clientConfig.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event) => {
|
||||||
|
this.bytesUploadedSoFar = event.loaded;
|
||||||
|
this.totalBytes = event.total;
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const resolved = await Promise.all([this.client.send(new import_client_s3.PutObjectCommand(params)), (_a = clientConfig == null ? void 0 : clientConfig.endpoint) == null ? void 0 : _a.call(clientConfig)]);
|
||||||
|
const putResult = resolved[0];
|
||||||
|
let endpoint = resolved[1];
|
||||||
|
if (!endpoint) {
|
||||||
|
endpoint = (0, import_middleware_endpoint.toEndpointV1)(
|
||||||
|
await (0, import_middleware_endpoint.getEndpointFromInstructions)(params, import_client_s3.PutObjectCommand, {
|
||||||
|
...clientConfig
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!endpoint) {
|
||||||
|
throw new Error('Could not resolve endpoint from S3 "client.config.endpoint()" nor EndpointsV2.');
|
||||||
|
}
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const locationKey = this.params.Key.split("/").map((segment) => (0, import_smithy_client.extendedEncodeURIComponent)(segment)).join("/");
|
||||||
|
const locationBucket = (0, import_smithy_client.extendedEncodeURIComponent)(this.params.Bucket);
|
||||||
|
const Location = (() => {
|
||||||
|
const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`);
|
||||||
|
const forcePathStyle = this.client.config.forcePathStyle;
|
||||||
|
if (forcePathStyle) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationBucket}/${locationKey}`;
|
||||||
|
}
|
||||||
|
if (endpointHostnameIncludesBucket) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationKey}`;
|
||||||
|
}
|
||||||
|
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}/${locationKey}`;
|
||||||
|
})();
|
||||||
|
this.singleUploadResult = {
|
||||||
|
...putResult,
|
||||||
|
Bucket: this.params.Bucket,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Location
|
||||||
|
};
|
||||||
|
const totalSize = byteLength(dataPart.data);
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: totalSize,
|
||||||
|
total: totalSize,
|
||||||
|
part: 1,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async __createMultipartUpload() {
|
||||||
|
if (!this.createMultiPartPromise) {
|
||||||
|
const createCommandParams = { ...this.params, Body: void 0 };
|
||||||
|
this.createMultiPartPromise = this.client.send(new import_client_s3.CreateMultipartUploadCommand(createCommandParams));
|
||||||
|
}
|
||||||
|
return this.createMultiPartPromise;
|
||||||
|
}
|
||||||
|
async __doConcurrentUpload(dataFeeder) {
|
||||||
|
for await (const dataPart of dataFeeder) {
|
||||||
|
if (this.uploadedParts.length > this.MAX_PARTS) {
|
||||||
|
throw new Error(
|
||||||
|
`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.params.Key} and ${this.params.Bucket}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dataPart.partNumber === 1 && dataPart.lastPart) {
|
||||||
|
return await this.__uploadUsingPut(dataPart);
|
||||||
|
}
|
||||||
|
if (!this.uploadId) {
|
||||||
|
const { UploadId } = await this.__createMultipartUpload();
|
||||||
|
this.uploadId = UploadId;
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const partSize = byteLength(dataPart.data) || 0;
|
||||||
|
const requestHandler = this.client.config.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
let lastSeenBytes = 0;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event, request) => {
|
||||||
|
const requestPartSize = Number(request.query["partNumber"]) || -1;
|
||||||
|
if (requestPartSize !== dataPart.partNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.total && partSize) {
|
||||||
|
this.bytesUploadedSoFar += event.loaded - lastSeenBytes;
|
||||||
|
lastSeenBytes = event.loaded;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const partResult = await this.client.send(
|
||||||
|
new import_client_s3.UploadPartCommand({
|
||||||
|
...this.params,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
Body: dataPart.data,
|
||||||
|
PartNumber: dataPart.partNumber
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!partResult.ETag) {
|
||||||
|
throw new Error(
|
||||||
|
`Part ${dataPart.partNumber} is missing ETag in UploadPart response. Missing Bucket CORS configuration for ETag header?`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.uploadedParts.push({
|
||||||
|
PartNumber: dataPart.partNumber,
|
||||||
|
ETag: partResult.ETag,
|
||||||
|
...partResult.ChecksumCRC32 && { ChecksumCRC32: partResult.ChecksumCRC32 },
|
||||||
|
...partResult.ChecksumCRC32C && { ChecksumCRC32C: partResult.ChecksumCRC32C },
|
||||||
|
...partResult.ChecksumSHA1 && { ChecksumSHA1: partResult.ChecksumSHA1 },
|
||||||
|
...partResult.ChecksumSHA256 && { ChecksumSHA256: partResult.ChecksumSHA256 }
|
||||||
|
});
|
||||||
|
if (eventEmitter === null) {
|
||||||
|
this.bytesUploadedSoFar += partSize;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (!this.uploadId) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (this.leavePartsOnError) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __doMultipartUpload() {
|
||||||
|
const dataFeeder = getChunk(this.params.Body, this.partSize);
|
||||||
|
for (let index = 0; index < this.queueSize; index++) {
|
||||||
|
const currentUpload = this.__doConcurrentUpload(dataFeeder);
|
||||||
|
this.concurrentUploaders.push(currentUpload);
|
||||||
|
}
|
||||||
|
await Promise.all(this.concurrentUploaders);
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
throw Object.assign(new Error("Upload aborted."), { name: "AbortError" });
|
||||||
|
}
|
||||||
|
let result;
|
||||||
|
if (this.isMultiPart) {
|
||||||
|
this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
|
||||||
|
const uploadCompleteParams = {
|
||||||
|
...this.params,
|
||||||
|
Body: void 0,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
MultipartUpload: {
|
||||||
|
Parts: this.uploadedParts
|
||||||
|
}
|
||||||
|
};
|
||||||
|
result = await this.client.send(new import_client_s3.CompleteMultipartUploadCommand(uploadCompleteParams));
|
||||||
|
if (typeof (result == null ? void 0 : result.Location) === "string" && result.Location.includes("%2F")) {
|
||||||
|
result.Location = result.Location.replace(/%2F/g, "/");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = this.singleUploadResult;
|
||||||
|
}
|
||||||
|
if (this.tags.length) {
|
||||||
|
await this.client.send(
|
||||||
|
new import_client_s3.PutObjectTaggingCommand({
|
||||||
|
...this.params,
|
||||||
|
Tagging: {
|
||||||
|
TagSet: this.tags
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
__notifyProgress(progress) {
|
||||||
|
if (this.uploadEvent) {
|
||||||
|
this.emit(this.uploadEvent, progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __abortTimeout(abortSignal) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
abortSignal.onabort = () => {
|
||||||
|
const abortError = new Error("Upload aborted.");
|
||||||
|
abortError.name = "AbortError";
|
||||||
|
reject(abortError);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
__validateInput() {
|
||||||
|
if (!this.params) {
|
||||||
|
throw new Error(`InputError: Upload requires params to be passed to upload.`);
|
||||||
|
}
|
||||||
|
if (!this.client) {
|
||||||
|
throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
|
||||||
|
}
|
||||||
|
if (this.partSize < MIN_PART_SIZE) {
|
||||||
|
throw new Error(
|
||||||
|
`EntityTooSmall: Your proposed upload partsize [${this.partSize}] is smaller than the minimum allowed size [${MIN_PART_SIZE}] (5MB)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.queueSize < 1) {
|
||||||
|
throw new Error(`Queue size: Must have at least one uploading queue.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_Upload, "Upload");
|
||||||
|
var Upload = _Upload;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3407:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientDefaultValues = void 0;
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
|
const runtimeConfig_shared_1 = __nccwpck_require__(9583);
|
||||||
|
exports.ClientDefaultValues = {
|
||||||
|
...runtimeConfig_shared_1.ClientSharedValues,
|
||||||
|
runtime: "node",
|
||||||
|
lstatSync: fs_1.lstatSync,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 9583:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientSharedValues = void 0;
|
||||||
|
exports.ClientSharedValues = {
|
||||||
|
lstatSync: () => { },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 6689:
|
/***/ 6689:
|
||||||
|
|
@ -27260,6 +27735,176 @@ var resolveRegionConfig = /* @__PURE__ */ __name((input) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5052:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
S3RequestPresigner: () => S3RequestPresigner,
|
||||||
|
getSignedUrl: () => getSignedUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var import_util_format_url = __nccwpck_require__(7053);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_protocol_http = __nccwpck_require__(9556);
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var import_signature_v4_multi_region = __nccwpck_require__(1856);
|
||||||
|
|
||||||
|
// src/constants.ts
|
||||||
|
var UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
|
||||||
|
var SHA256_HEADER = "X-Amz-Content-Sha256";
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var _S3RequestPresigner = class _S3RequestPresigner {
|
||||||
|
constructor(options) {
|
||||||
|
const resolvedOptions = {
|
||||||
|
// Allow `signingName` because we want to support usecase of supply client's resolved config
|
||||||
|
// directly. Where service equals signingName.
|
||||||
|
service: options.signingName || options.service || "s3",
|
||||||
|
uriEscapePath: options.uriEscapePath || false,
|
||||||
|
applyChecksum: options.applyChecksum || false,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
this.signer = new import_signature_v4_multi_region.SignatureV4MultiRegion(resolvedOptions);
|
||||||
|
}
|
||||||
|
presign(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presign(requestToSign, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
presignWithCredentials(requestToSign, credentials, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presignWithCredentials(requestToSign, credentials, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
prepareRequest(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set() } = {}) {
|
||||||
|
unsignableHeaders.add("content-type");
|
||||||
|
Object.keys(requestToSign.headers).map((header) => header.toLowerCase()).filter((header) => header.startsWith("x-amz-server-side-encryption")).forEach((header) => {
|
||||||
|
unhoistableHeaders.add(header);
|
||||||
|
});
|
||||||
|
requestToSign.headers[SHA256_HEADER] = UNSIGNED_PAYLOAD;
|
||||||
|
const currentHostHeader = requestToSign.headers.host;
|
||||||
|
const port = requestToSign.port;
|
||||||
|
const expectedHostHeader = `${requestToSign.hostname}${requestToSign.port != null ? ":" + port : ""}`;
|
||||||
|
if (!currentHostHeader || currentHostHeader === requestToSign.hostname && requestToSign.port != null) {
|
||||||
|
requestToSign.headers.host = expectedHostHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_S3RequestPresigner, "S3RequestPresigner");
|
||||||
|
var S3RequestPresigner = _S3RequestPresigner;
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var getSignedUrl = /* @__PURE__ */ __name(async (client, command, options = {}) => {
|
||||||
|
var _a, _b, _c;
|
||||||
|
let s3Presigner;
|
||||||
|
let region;
|
||||||
|
if (typeof client.config.endpointProvider === "function") {
|
||||||
|
const endpointV2 = await (0, import_middleware_endpoint.getEndpointFromInstructions)(
|
||||||
|
command.input,
|
||||||
|
command.constructor,
|
||||||
|
client.config
|
||||||
|
);
|
||||||
|
const authScheme = (_b = (_a = endpointV2.properties) == null ? void 0 : _a.authSchemes) == null ? void 0 : _b[0];
|
||||||
|
if ((authScheme == null ? void 0 : authScheme.name) === "sigv4a") {
|
||||||
|
region = (_c = authScheme == null ? void 0 : authScheme.signingRegionSet) == null ? void 0 : _c.join(",");
|
||||||
|
} else {
|
||||||
|
region = authScheme == null ? void 0 : authScheme.signingRegion;
|
||||||
|
}
|
||||||
|
s3Presigner = new S3RequestPresigner({
|
||||||
|
...client.config,
|
||||||
|
signingName: authScheme == null ? void 0 : authScheme.signingName,
|
||||||
|
region: async () => region
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
s3Presigner = new S3RequestPresigner(client.config);
|
||||||
|
}
|
||||||
|
const presignInterceptMiddleware = /* @__PURE__ */ __name((next, context) => async (args) => {
|
||||||
|
const { request } = args;
|
||||||
|
if (!import_protocol_http.HttpRequest.isInstance(request)) {
|
||||||
|
throw new Error("Request to be presigned is not an valid HTTP request.");
|
||||||
|
}
|
||||||
|
delete request.headers["amz-sdk-invocation-id"];
|
||||||
|
delete request.headers["amz-sdk-request"];
|
||||||
|
delete request.headers["x-amz-user-agent"];
|
||||||
|
let presigned2;
|
||||||
|
const presignerOptions = {
|
||||||
|
...options,
|
||||||
|
signingRegion: options.signingRegion ?? context["signing_region"] ?? region,
|
||||||
|
signingService: options.signingService ?? context["signing_service"]
|
||||||
|
};
|
||||||
|
if (context.s3ExpressIdentity) {
|
||||||
|
presigned2 = await s3Presigner.presignWithCredentials(request, context.s3ExpressIdentity, presignerOptions);
|
||||||
|
} else {
|
||||||
|
presigned2 = await s3Presigner.presign(request, presignerOptions);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
// Intercept the middleware stack by returning fake response
|
||||||
|
response: {},
|
||||||
|
output: {
|
||||||
|
$metadata: { httpStatusCode: 200 },
|
||||||
|
presigned: presigned2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, "presignInterceptMiddleware");
|
||||||
|
const middlewareName = "presignInterceptMiddleware";
|
||||||
|
const clientStack = client.middlewareStack.clone();
|
||||||
|
clientStack.addRelativeTo(presignInterceptMiddleware, {
|
||||||
|
name: middlewareName,
|
||||||
|
relation: "before",
|
||||||
|
toMiddleware: "awsAuthMiddleware",
|
||||||
|
override: true
|
||||||
|
});
|
||||||
|
const handler = command.resolveMiddleware(clientStack, client.config, {});
|
||||||
|
const { output } = await handler({ input: command.input });
|
||||||
|
const { presigned } = output;
|
||||||
|
return (0, import_util_format_url.formatUrl)(presigned);
|
||||||
|
}, "getSignedUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 1856:
|
/***/ 1856:
|
||||||
|
|
@ -28054,6 +28699,72 @@ import_util_endpoints.customEndpointFunctions.aws = awsEndpointFunctions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7053:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
formatUrl: () => formatUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
var import_querystring_builder = __nccwpck_require__(8031);
|
||||||
|
function formatUrl(request) {
|
||||||
|
const { port, query } = request;
|
||||||
|
let { protocol, path, hostname } = request;
|
||||||
|
if (protocol && protocol.slice(-1) !== ":") {
|
||||||
|
protocol += ":";
|
||||||
|
}
|
||||||
|
if (port) {
|
||||||
|
hostname += `:${port}`;
|
||||||
|
}
|
||||||
|
if (path && path.charAt(0) !== "/") {
|
||||||
|
path = `/${path}`;
|
||||||
|
}
|
||||||
|
let queryString = query ? (0, import_querystring_builder.buildQueryString)(query) : "";
|
||||||
|
if (queryString && queryString[0] !== "?") {
|
||||||
|
queryString = `?${queryString}`;
|
||||||
|
}
|
||||||
|
let auth = "";
|
||||||
|
if (request.username != null || request.password != null) {
|
||||||
|
const username = request.username ?? "";
|
||||||
|
const password = request.password ?? "";
|
||||||
|
auth = `${username}:${password}@`;
|
||||||
|
}
|
||||||
|
let fragment = "";
|
||||||
|
if (request.fragment) {
|
||||||
|
fragment = `#${request.fragment}`;
|
||||||
|
}
|
||||||
|
return `${protocol}//${auth}${hostname}${path}${queryString}${fragment}`;
|
||||||
|
}
|
||||||
|
__name(formatUrl, "formatUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 8095:
|
/***/ 8095:
|
||||||
|
|
@ -66451,6 +67162,92 @@ exports.VERSION = void 0;
|
||||||
exports.VERSION = '1.4.0';
|
exports.VERSION = '1.4.0';
|
||||||
//# sourceMappingURL=version.js.map
|
//# sourceMappingURL=version.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7020:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
AbortController: () => AbortController,
|
||||||
|
AbortHandler: () => import_types.AbortHandler,
|
||||||
|
AbortSignal: () => AbortSignal,
|
||||||
|
IAbortController: () => import_types.AbortController,
|
||||||
|
IAbortSignal: () => import_types.AbortSignal
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
|
||||||
|
|
||||||
|
// src/AbortSignal.ts
|
||||||
|
var import_types = __nccwpck_require__(5756);
|
||||||
|
var _AbortSignal = class _AbortSignal {
|
||||||
|
constructor() {
|
||||||
|
this.onabort = null;
|
||||||
|
this._aborted = false;
|
||||||
|
Object.defineProperty(this, "_aborted", {
|
||||||
|
value: false,
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether the associated operation has already been cancelled.
|
||||||
|
*/
|
||||||
|
get aborted() {
|
||||||
|
return this._aborted;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
abort() {
|
||||||
|
this._aborted = true;
|
||||||
|
if (this.onabort) {
|
||||||
|
this.onabort(this);
|
||||||
|
this.onabort = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortSignal, "AbortSignal");
|
||||||
|
var AbortSignal = _AbortSignal;
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
var _AbortController = class _AbortController {
|
||||||
|
constructor() {
|
||||||
|
this.signal = new AbortSignal();
|
||||||
|
}
|
||||||
|
abort() {
|
||||||
|
this.signal.abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortController, "AbortController");
|
||||||
|
var AbortController = _AbortController;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 3098:
|
/***/ 3098:
|
||||||
|
|
@ -92969,12 +93766,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
||||||
const client_s3_1 = __nccwpck_require__(9250);
|
const client_s3_1 = __nccwpck_require__(9250);
|
||||||
const child_process_1 = __nccwpck_require__(2081);
|
const { getSignedUrl } = __nccwpck_require__(5052);
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
const crypto = __importStar(__nccwpck_require__(6113));
|
const crypto = __importStar(__nccwpck_require__(6113));
|
||||||
|
const options_1 = __nccwpck_require__(6215);
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const utils = __importStar(__nccwpck_require__(1518));
|
const utils = __importStar(__nccwpck_require__(1518));
|
||||||
|
const lib_storage_1 = __nccwpck_require__(3087);
|
||||||
|
const downloadUtils_1 = __nccwpck_require__(6968);
|
||||||
const versionSalt = "1.0";
|
const versionSalt = "1.0";
|
||||||
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
||||||
|
const region = process.env.RUNS_ON_AWS_REGION ||
|
||||||
|
process.env.AWS_REGION ||
|
||||||
|
process.env.AWS_DEFAULT_REGION;
|
||||||
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
||||||
// don't pass changes upstream
|
// don't pass changes upstream
|
||||||
const components = paths.slice();
|
const components = paths.slice();
|
||||||
|
|
@ -92995,31 +93799,33 @@ function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false)
|
||||||
.digest("hex");
|
.digest("hex");
|
||||||
}
|
}
|
||||||
exports.getCacheVersion = getCacheVersion;
|
exports.getCacheVersion = getCacheVersion;
|
||||||
function getCacheEntryS3Key(restoreKey, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getS3Prefix(paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
const repository = process.env.GITHUB_REPOSITORY;
|
const repository = process.env.GITHUB_REPOSITORY;
|
||||||
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
||||||
return ["cache", repository, version, restoreKey].join("/");
|
return ["cache", repository, version].join("/");
|
||||||
}
|
}
|
||||||
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const cacheEntry = {};
|
const cacheEntry = {};
|
||||||
const s3Client = new client_s3_1.S3Client();
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
// Find the most recent key matching one of the restoreKeys prefixes
|
// Find the most recent key matching one of the restoreKeys prefixes
|
||||||
for (const restoreKey of keys) {
|
for (const restoreKey of keys) {
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
|
compressionMethod,
|
||||||
|
enableCrossOsArchive
|
||||||
|
});
|
||||||
const listObjectsParams = {
|
const listObjectsParams = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Prefix: getCacheEntryS3Key(restoreKey, paths, {
|
Prefix: [s3Prefix, restoreKey].join("/")
|
||||||
compressionMethod,
|
|
||||||
enableCrossOsArchive
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
||||||
if (Contents.length > 0) {
|
if (Contents.length > 0) {
|
||||||
// Sort keys by LastModified time in descending order
|
// Sort keys by LastModified time in descending order
|
||||||
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
||||||
cacheEntry.cacheKey = sortedKeys[0].Key; // Return the most recent key
|
const s3Path = sortedKeys[0].Key; // Return the most recent key
|
||||||
cacheEntry.archiveLocation = `s3://${bucketName}/${cacheEntry.cacheKey}`;
|
cacheEntry.cacheKey = s3Path === null || s3Path === void 0 ? void 0 : s3Path.replace(`${s3Prefix}/`, "");
|
||||||
|
cacheEntry.archiveLocation = `s3://${bucketName}/${s3Path}`;
|
||||||
return cacheEntry;
|
return cacheEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93027,7 +93833,6 @@ function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive })
|
||||||
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`No matching keys found in bucket ${bucketName}`);
|
|
||||||
return cacheEntry; // No keys found
|
return cacheEntry; // No keys found
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -93037,26 +93842,21 @@ function downloadCache(archiveLocation, archivePath, options) {
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const downloadProcess = (0, child_process_1.spawn)("aws", [
|
if (!region) {
|
||||||
"s3",
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
"cp",
|
}
|
||||||
archiveLocation,
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
archivePath
|
const archiveUrl = new URL(archiveLocation);
|
||||||
]);
|
const objectKey = archiveUrl.pathname.slice(1);
|
||||||
return new Promise((resolve, reject) => {
|
const command = new client_s3_1.GetObjectCommand({
|
||||||
downloadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
Bucket: bucketName,
|
||||||
downloadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
Key: objectKey
|
||||||
downloadProcess.on("close", code => {
|
|
||||||
if (code === 0) {
|
|
||||||
console.log(`File downloaded successfully from ${archiveLocation} to ${archivePath}`);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(`File download failed with code ${code}`);
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
const url = yield getSignedUrl(s3Client, command, {
|
||||||
|
expiresIn: 3600
|
||||||
|
});
|
||||||
|
const downloadOptions = (0, options_1.getDownloadOptions)(Object.assign(Object.assign({}, options), { downloadConcurrency: 14, concurrentBlobDownloads: true }));
|
||||||
|
yield (0, downloadUtils_1.downloadCacheHttpClientConcurrent)(url, archivePath, downloadOptions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.downloadCache = downloadCache;
|
exports.downloadCache = downloadCache;
|
||||||
|
|
@ -93065,33 +93865,36 @@ function saveCache(key, paths, archivePath, { compressionMethod, enableCrossOsAr
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const s3Key = getCacheEntryS3Key(key, paths, {
|
if (!region) {
|
||||||
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
|
}
|
||||||
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
compressionMethod,
|
compressionMethod,
|
||||||
enableCrossOsArchive
|
enableCrossOsArchive
|
||||||
});
|
});
|
||||||
const archiveLocation = `s3://${bucketName}/${s3Key}`;
|
const s3Key = `${s3Prefix}/${key}`;
|
||||||
const uploadProcess = (0, child_process_1.spawn)("aws", [
|
const multipartUpload = new lib_storage_1.Upload({
|
||||||
"s3",
|
client: s3Client,
|
||||||
"cp",
|
params: {
|
||||||
archivePath,
|
Bucket: bucketName,
|
||||||
archiveLocation
|
Key: s3Key,
|
||||||
]);
|
Body: (0, fs_1.createReadStream)(archivePath)
|
||||||
|
},
|
||||||
|
// Part size in bytes
|
||||||
|
partSize: 32 * 1024 * 1024,
|
||||||
|
// Max concurrency
|
||||||
|
queueSize: 14
|
||||||
|
});
|
||||||
// Commit Cache
|
// Commit Cache
|
||||||
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||||
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
||||||
const code = yield new Promise((resolve, reject) => {
|
core.info(`Uploading cache from ${archivePath} to ${bucketName}/${s3Key}`);
|
||||||
uploadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
multipartUpload.on("httpUploadProgress", progress => {
|
||||||
uploadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
core.info(`Uploaded ${progress.part}/${progress.total}.`);
|
||||||
uploadProcess.on("close", code => {
|
|
||||||
resolve(code);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
if (code === 0) {
|
yield multipartUpload.done();
|
||||||
core.info(`Cache saved successfully.`);
|
core.info(`Cache saved successfully.`);
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`File upload failed with code ${code}.`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
@ -93324,6 +94127,283 @@ function saveCache(paths, key, options, enableCrossOsArchive = false) {
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 6968:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.downloadCacheHttpClientConcurrent = exports.DownloadProgress = void 0;
|
||||||
|
// Just a copy of the original file from the toolkit/actions/cache repository, with a change for byte range used in the downloadCacheHttpClientConcurrent function.
|
||||||
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
|
const http_client_1 = __nccwpck_require__(6255);
|
||||||
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
|
const requestUtils_1 = __nccwpck_require__(3981);
|
||||||
|
/**
|
||||||
|
* Class for tracking the download state and displaying stats.
|
||||||
|
*/
|
||||||
|
class DownloadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.segmentIndex = 0;
|
||||||
|
this.segmentSize = 0;
|
||||||
|
this.segmentOffset = 0;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Progress to the next segment. Only call this method when the previous segment
|
||||||
|
* is complete.
|
||||||
|
*
|
||||||
|
* @param segmentSize the length of the next segment
|
||||||
|
*/
|
||||||
|
nextSegment(segmentSize) {
|
||||||
|
this.segmentOffset = this.segmentOffset + this.segmentSize;
|
||||||
|
this.segmentIndex = this.segmentIndex + 1;
|
||||||
|
this.segmentSize = segmentSize;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
core.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes received for the current segment.
|
||||||
|
*
|
||||||
|
* @param receivedBytes the number of bytes received
|
||||||
|
*/
|
||||||
|
setReceivedBytes(receivedBytes) {
|
||||||
|
this.receivedBytes = receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.segmentOffset + this.receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the download is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current download stats. Once the download completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.segmentOffset + this.receivedBytes;
|
||||||
|
const percentage = (100 *
|
||||||
|
(transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const downloadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setReceivedBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the download
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.DownloadProgress = DownloadProgress;
|
||||||
|
/**
|
||||||
|
* Download the cache using the Actions toolkit http-client concurrently
|
||||||
|
*
|
||||||
|
* @param archiveLocation the URL for the cache
|
||||||
|
* @param archivePath the local path where the cache is saved
|
||||||
|
*/
|
||||||
|
function downloadCacheHttpClientConcurrent(archiveLocation, archivePath, options) {
|
||||||
|
var _a;
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const archiveDescriptor = yield fs.promises.open(archivePath, "w");
|
||||||
|
const httpClient = new http_client_1.HttpClient("actions/cache", undefined, {
|
||||||
|
socketTimeout: options.timeoutInMs,
|
||||||
|
keepAlive: true
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const res = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCacheMetadata", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.request("GET", archiveLocation, null, {
|
||||||
|
Range: "bytes=0-1"
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
const contentRange = res.message.headers["content-range"];
|
||||||
|
if (!contentRange) {
|
||||||
|
throw new Error("Range request not supported by server");
|
||||||
|
}
|
||||||
|
const match = contentRange === null || contentRange === void 0 ? void 0 : contentRange.match(/bytes \d+-\d+\/(\d+)/);
|
||||||
|
if (!match) {
|
||||||
|
throw new Error("Content-Range header in server response not in correct format");
|
||||||
|
}
|
||||||
|
const length = parseInt(match[1]);
|
||||||
|
if (Number.isNaN(length)) {
|
||||||
|
throw new Error(`Could not interpret Content-Length: ${length}`);
|
||||||
|
}
|
||||||
|
const downloads = [];
|
||||||
|
const blockSize = 32 * 1024 * 1024;
|
||||||
|
for (let offset = 0; offset < length; offset += blockSize) {
|
||||||
|
const count = Math.min(blockSize, length - offset);
|
||||||
|
downloads.push({
|
||||||
|
offset,
|
||||||
|
promiseGetter: () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield downloadSegmentRetry(httpClient, archiveLocation, offset, count);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// reverse to use .pop instead of .shift
|
||||||
|
downloads.reverse();
|
||||||
|
let actives = 0;
|
||||||
|
let bytesDownloaded = 0;
|
||||||
|
const progress = new DownloadProgress(length);
|
||||||
|
progress.startDisplayTimer();
|
||||||
|
const progressFn = progress.onProgress();
|
||||||
|
const activeDownloads = [];
|
||||||
|
let nextDownload;
|
||||||
|
const waitAndWrite = () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const segment = yield Promise.race(Object.values(activeDownloads));
|
||||||
|
yield archiveDescriptor.write(segment.buffer, 0, segment.count, segment.offset);
|
||||||
|
actives--;
|
||||||
|
delete activeDownloads[segment.offset];
|
||||||
|
bytesDownloaded += segment.count;
|
||||||
|
progressFn({ loadedBytes: bytesDownloaded });
|
||||||
|
});
|
||||||
|
while ((nextDownload = downloads.pop())) {
|
||||||
|
activeDownloads[nextDownload.offset] = nextDownload.promiseGetter();
|
||||||
|
actives++;
|
||||||
|
if (actives >= ((_a = options.downloadConcurrency) !== null && _a !== void 0 ? _a : 10)) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (actives > 0) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
httpClient.dispose();
|
||||||
|
yield archiveDescriptor.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent;
|
||||||
|
function downloadSegmentRetry(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const retries = 5;
|
||||||
|
let failures = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const timeout = 30000;
|
||||||
|
const result = yield promiseWithTimeout(timeout, downloadSegment(httpClient, archiveLocation, offset, count));
|
||||||
|
if (typeof result === "string") {
|
||||||
|
throw new Error("downloadSegmentRetry failed due to timeout");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (failures >= retries) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function downloadSegment(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const partRes = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCachePart", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.get(archiveLocation, {
|
||||||
|
Range: `bytes=${offset}-${offset + count - 1}`
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
if (!partRes.readBodyBuffer) {
|
||||||
|
throw new Error("Expected HttpClientResponse to implement readBodyBuffer");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
offset,
|
||||||
|
count,
|
||||||
|
buffer: yield partRes.readBodyBuffer()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const promiseWithTimeout = (timeoutMs, promise) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
|
let timeoutHandle;
|
||||||
|
const timeoutPromise = new Promise(resolve => {
|
||||||
|
timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
|
||||||
|
});
|
||||||
|
return Promise.race([promise, timeoutPromise]).then(result => {
|
||||||
|
clearTimeout(timeoutHandle);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 2357:
|
/***/ 2357:
|
||||||
|
|
|
||||||
|
|
@ -25009,6 +25009,481 @@ const client_sts_1 = __nccwpck_require__(2209);
|
||||||
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3087:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
Upload: () => Upload
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var import_client_s3 = __nccwpck_require__(9250);
|
||||||
|
var import_abort_controller = __nccwpck_require__(7020);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_smithy_client = __nccwpck_require__(3570);
|
||||||
|
var import_events = __nccwpck_require__(2361);
|
||||||
|
|
||||||
|
// src/bytelength.ts
|
||||||
|
var import_runtimeConfig = __nccwpck_require__(3407);
|
||||||
|
var byteLength = /* @__PURE__ */ __name((input) => {
|
||||||
|
if (input === null || input === void 0)
|
||||||
|
return 0;
|
||||||
|
if (typeof input === "string")
|
||||||
|
input = Buffer.from(input);
|
||||||
|
if (typeof input.byteLength === "number") {
|
||||||
|
return input.byteLength;
|
||||||
|
} else if (typeof input.length === "number") {
|
||||||
|
return input.length;
|
||||||
|
} else if (typeof input.size === "number") {
|
||||||
|
return input.size;
|
||||||
|
} else if (typeof input.path === "string") {
|
||||||
|
try {
|
||||||
|
return import_runtimeConfig.ClientDefaultValues.lstatSync(input.path).size;
|
||||||
|
} catch (error) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return void 0;
|
||||||
|
}, "byteLength");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
|
||||||
|
var import_stream = __nccwpck_require__(2781);
|
||||||
|
|
||||||
|
// src/chunks/getChunkBuffer.ts
|
||||||
|
async function* getChunkBuffer(data, partSize) {
|
||||||
|
let partNumber = 1;
|
||||||
|
let startByte = 0;
|
||||||
|
let endByte = partSize;
|
||||||
|
while (endByte < data.byteLength) {
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte, endByte)
|
||||||
|
};
|
||||||
|
partNumber += 1;
|
||||||
|
startByte = endByte;
|
||||||
|
endByte = startByte + partSize;
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkBuffer, "getChunkBuffer");
|
||||||
|
|
||||||
|
// src/chunks/getChunkStream.ts
|
||||||
|
var import_buffer = __nccwpck_require__(4300);
|
||||||
|
async function* getChunkStream(data, partSize, getNextData) {
|
||||||
|
let partNumber = 1;
|
||||||
|
const currentBuffer = { chunks: [], length: 0 };
|
||||||
|
for await (const datum of getNextData(data)) {
|
||||||
|
currentBuffer.chunks.push(datum);
|
||||||
|
currentBuffer.length += datum.length;
|
||||||
|
while (currentBuffer.length >= partSize) {
|
||||||
|
const dataChunk = currentBuffer.chunks.length > 1 ? import_buffer.Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0];
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: dataChunk.slice(0, partSize)
|
||||||
|
};
|
||||||
|
currentBuffer.chunks = [dataChunk.slice(partSize)];
|
||||||
|
currentBuffer.length = currentBuffer.chunks[0].length;
|
||||||
|
partNumber += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: import_buffer.Buffer.concat(currentBuffer.chunks),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkStream, "getChunkStream");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadable.ts
|
||||||
|
|
||||||
|
async function* getDataReadable(data) {
|
||||||
|
for await (const chunk of data) {
|
||||||
|
yield import_buffer.Buffer.from(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadable, "getDataReadable");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadableStream.ts
|
||||||
|
|
||||||
|
async function* getDataReadableStream(data) {
|
||||||
|
const reader = data.getReader();
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done)
|
||||||
|
return;
|
||||||
|
yield import_buffer.Buffer.from(value);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
reader.releaseLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadableStream, "getDataReadableStream");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
var getChunk = /* @__PURE__ */ __name((data, partSize) => {
|
||||||
|
if (data instanceof import_buffer.Buffer) {
|
||||||
|
return getChunkBuffer(data, partSize);
|
||||||
|
} else if (data instanceof import_stream.Readable) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadable);
|
||||||
|
} else if (data instanceof String || typeof data === "string" || data instanceof Uint8Array) {
|
||||||
|
return getChunkBuffer(import_buffer.Buffer.from(data), partSize);
|
||||||
|
}
|
||||||
|
if (typeof data.stream === "function") {
|
||||||
|
return getChunkStream(data.stream(), partSize, getDataReadableStream);
|
||||||
|
} else if (data instanceof ReadableStream) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadableStream);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
"Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, "getChunk");
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var MIN_PART_SIZE = 1024 * 1024 * 5;
|
||||||
|
var _Upload = class _Upload extends import_events.EventEmitter {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
/**
|
||||||
|
* S3 multipart upload does not allow more than 10000 parts.
|
||||||
|
*/
|
||||||
|
this.MAX_PARTS = 1e4;
|
||||||
|
// Defaults.
|
||||||
|
this.queueSize = 4;
|
||||||
|
this.partSize = MIN_PART_SIZE;
|
||||||
|
this.leavePartsOnError = false;
|
||||||
|
this.tags = [];
|
||||||
|
this.concurrentUploaders = [];
|
||||||
|
this.uploadedParts = [];
|
||||||
|
this.isMultiPart = true;
|
||||||
|
this.queueSize = options.queueSize || this.queueSize;
|
||||||
|
this.partSize = options.partSize || this.partSize;
|
||||||
|
this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
|
||||||
|
this.tags = options.tags || this.tags;
|
||||||
|
this.client = options.client;
|
||||||
|
this.params = options.params;
|
||||||
|
this.__validateInput();
|
||||||
|
this.totalBytes = byteLength(this.params.Body);
|
||||||
|
this.bytesUploadedSoFar = 0;
|
||||||
|
this.abortController = options.abortController ?? new import_abort_controller.AbortController();
|
||||||
|
}
|
||||||
|
async abort() {
|
||||||
|
this.abortController.abort();
|
||||||
|
}
|
||||||
|
async done() {
|
||||||
|
return await Promise.race([this.__doMultipartUpload(), this.__abortTimeout(this.abortController.signal)]);
|
||||||
|
}
|
||||||
|
on(event, listener) {
|
||||||
|
this.uploadEvent = event;
|
||||||
|
return super.on(event, listener);
|
||||||
|
}
|
||||||
|
async __uploadUsingPut(dataPart) {
|
||||||
|
var _a;
|
||||||
|
this.isMultiPart = false;
|
||||||
|
const params = { ...this.params, Body: dataPart.data };
|
||||||
|
const clientConfig = this.client.config;
|
||||||
|
const requestHandler = clientConfig.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event) => {
|
||||||
|
this.bytesUploadedSoFar = event.loaded;
|
||||||
|
this.totalBytes = event.total;
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const resolved = await Promise.all([this.client.send(new import_client_s3.PutObjectCommand(params)), (_a = clientConfig == null ? void 0 : clientConfig.endpoint) == null ? void 0 : _a.call(clientConfig)]);
|
||||||
|
const putResult = resolved[0];
|
||||||
|
let endpoint = resolved[1];
|
||||||
|
if (!endpoint) {
|
||||||
|
endpoint = (0, import_middleware_endpoint.toEndpointV1)(
|
||||||
|
await (0, import_middleware_endpoint.getEndpointFromInstructions)(params, import_client_s3.PutObjectCommand, {
|
||||||
|
...clientConfig
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!endpoint) {
|
||||||
|
throw new Error('Could not resolve endpoint from S3 "client.config.endpoint()" nor EndpointsV2.');
|
||||||
|
}
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const locationKey = this.params.Key.split("/").map((segment) => (0, import_smithy_client.extendedEncodeURIComponent)(segment)).join("/");
|
||||||
|
const locationBucket = (0, import_smithy_client.extendedEncodeURIComponent)(this.params.Bucket);
|
||||||
|
const Location = (() => {
|
||||||
|
const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`);
|
||||||
|
const forcePathStyle = this.client.config.forcePathStyle;
|
||||||
|
if (forcePathStyle) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationBucket}/${locationKey}`;
|
||||||
|
}
|
||||||
|
if (endpointHostnameIncludesBucket) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationKey}`;
|
||||||
|
}
|
||||||
|
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}/${locationKey}`;
|
||||||
|
})();
|
||||||
|
this.singleUploadResult = {
|
||||||
|
...putResult,
|
||||||
|
Bucket: this.params.Bucket,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Location
|
||||||
|
};
|
||||||
|
const totalSize = byteLength(dataPart.data);
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: totalSize,
|
||||||
|
total: totalSize,
|
||||||
|
part: 1,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async __createMultipartUpload() {
|
||||||
|
if (!this.createMultiPartPromise) {
|
||||||
|
const createCommandParams = { ...this.params, Body: void 0 };
|
||||||
|
this.createMultiPartPromise = this.client.send(new import_client_s3.CreateMultipartUploadCommand(createCommandParams));
|
||||||
|
}
|
||||||
|
return this.createMultiPartPromise;
|
||||||
|
}
|
||||||
|
async __doConcurrentUpload(dataFeeder) {
|
||||||
|
for await (const dataPart of dataFeeder) {
|
||||||
|
if (this.uploadedParts.length > this.MAX_PARTS) {
|
||||||
|
throw new Error(
|
||||||
|
`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.params.Key} and ${this.params.Bucket}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dataPart.partNumber === 1 && dataPart.lastPart) {
|
||||||
|
return await this.__uploadUsingPut(dataPart);
|
||||||
|
}
|
||||||
|
if (!this.uploadId) {
|
||||||
|
const { UploadId } = await this.__createMultipartUpload();
|
||||||
|
this.uploadId = UploadId;
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const partSize = byteLength(dataPart.data) || 0;
|
||||||
|
const requestHandler = this.client.config.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
let lastSeenBytes = 0;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event, request) => {
|
||||||
|
const requestPartSize = Number(request.query["partNumber"]) || -1;
|
||||||
|
if (requestPartSize !== dataPart.partNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.total && partSize) {
|
||||||
|
this.bytesUploadedSoFar += event.loaded - lastSeenBytes;
|
||||||
|
lastSeenBytes = event.loaded;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const partResult = await this.client.send(
|
||||||
|
new import_client_s3.UploadPartCommand({
|
||||||
|
...this.params,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
Body: dataPart.data,
|
||||||
|
PartNumber: dataPart.partNumber
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!partResult.ETag) {
|
||||||
|
throw new Error(
|
||||||
|
`Part ${dataPart.partNumber} is missing ETag in UploadPart response. Missing Bucket CORS configuration for ETag header?`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.uploadedParts.push({
|
||||||
|
PartNumber: dataPart.partNumber,
|
||||||
|
ETag: partResult.ETag,
|
||||||
|
...partResult.ChecksumCRC32 && { ChecksumCRC32: partResult.ChecksumCRC32 },
|
||||||
|
...partResult.ChecksumCRC32C && { ChecksumCRC32C: partResult.ChecksumCRC32C },
|
||||||
|
...partResult.ChecksumSHA1 && { ChecksumSHA1: partResult.ChecksumSHA1 },
|
||||||
|
...partResult.ChecksumSHA256 && { ChecksumSHA256: partResult.ChecksumSHA256 }
|
||||||
|
});
|
||||||
|
if (eventEmitter === null) {
|
||||||
|
this.bytesUploadedSoFar += partSize;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (!this.uploadId) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (this.leavePartsOnError) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __doMultipartUpload() {
|
||||||
|
const dataFeeder = getChunk(this.params.Body, this.partSize);
|
||||||
|
for (let index = 0; index < this.queueSize; index++) {
|
||||||
|
const currentUpload = this.__doConcurrentUpload(dataFeeder);
|
||||||
|
this.concurrentUploaders.push(currentUpload);
|
||||||
|
}
|
||||||
|
await Promise.all(this.concurrentUploaders);
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
throw Object.assign(new Error("Upload aborted."), { name: "AbortError" });
|
||||||
|
}
|
||||||
|
let result;
|
||||||
|
if (this.isMultiPart) {
|
||||||
|
this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
|
||||||
|
const uploadCompleteParams = {
|
||||||
|
...this.params,
|
||||||
|
Body: void 0,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
MultipartUpload: {
|
||||||
|
Parts: this.uploadedParts
|
||||||
|
}
|
||||||
|
};
|
||||||
|
result = await this.client.send(new import_client_s3.CompleteMultipartUploadCommand(uploadCompleteParams));
|
||||||
|
if (typeof (result == null ? void 0 : result.Location) === "string" && result.Location.includes("%2F")) {
|
||||||
|
result.Location = result.Location.replace(/%2F/g, "/");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = this.singleUploadResult;
|
||||||
|
}
|
||||||
|
if (this.tags.length) {
|
||||||
|
await this.client.send(
|
||||||
|
new import_client_s3.PutObjectTaggingCommand({
|
||||||
|
...this.params,
|
||||||
|
Tagging: {
|
||||||
|
TagSet: this.tags
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
__notifyProgress(progress) {
|
||||||
|
if (this.uploadEvent) {
|
||||||
|
this.emit(this.uploadEvent, progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __abortTimeout(abortSignal) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
abortSignal.onabort = () => {
|
||||||
|
const abortError = new Error("Upload aborted.");
|
||||||
|
abortError.name = "AbortError";
|
||||||
|
reject(abortError);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
__validateInput() {
|
||||||
|
if (!this.params) {
|
||||||
|
throw new Error(`InputError: Upload requires params to be passed to upload.`);
|
||||||
|
}
|
||||||
|
if (!this.client) {
|
||||||
|
throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
|
||||||
|
}
|
||||||
|
if (this.partSize < MIN_PART_SIZE) {
|
||||||
|
throw new Error(
|
||||||
|
`EntityTooSmall: Your proposed upload partsize [${this.partSize}] is smaller than the minimum allowed size [${MIN_PART_SIZE}] (5MB)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.queueSize < 1) {
|
||||||
|
throw new Error(`Queue size: Must have at least one uploading queue.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_Upload, "Upload");
|
||||||
|
var Upload = _Upload;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3407:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientDefaultValues = void 0;
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
|
const runtimeConfig_shared_1 = __nccwpck_require__(9583);
|
||||||
|
exports.ClientDefaultValues = {
|
||||||
|
...runtimeConfig_shared_1.ClientSharedValues,
|
||||||
|
runtime: "node",
|
||||||
|
lstatSync: fs_1.lstatSync,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 9583:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientSharedValues = void 0;
|
||||||
|
exports.ClientSharedValues = {
|
||||||
|
lstatSync: () => { },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 6689:
|
/***/ 6689:
|
||||||
|
|
@ -27260,6 +27735,176 @@ var resolveRegionConfig = /* @__PURE__ */ __name((input) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5052:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
S3RequestPresigner: () => S3RequestPresigner,
|
||||||
|
getSignedUrl: () => getSignedUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var import_util_format_url = __nccwpck_require__(7053);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_protocol_http = __nccwpck_require__(9556);
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var import_signature_v4_multi_region = __nccwpck_require__(1856);
|
||||||
|
|
||||||
|
// src/constants.ts
|
||||||
|
var UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
|
||||||
|
var SHA256_HEADER = "X-Amz-Content-Sha256";
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var _S3RequestPresigner = class _S3RequestPresigner {
|
||||||
|
constructor(options) {
|
||||||
|
const resolvedOptions = {
|
||||||
|
// Allow `signingName` because we want to support usecase of supply client's resolved config
|
||||||
|
// directly. Where service equals signingName.
|
||||||
|
service: options.signingName || options.service || "s3",
|
||||||
|
uriEscapePath: options.uriEscapePath || false,
|
||||||
|
applyChecksum: options.applyChecksum || false,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
this.signer = new import_signature_v4_multi_region.SignatureV4MultiRegion(resolvedOptions);
|
||||||
|
}
|
||||||
|
presign(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presign(requestToSign, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
presignWithCredentials(requestToSign, credentials, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presignWithCredentials(requestToSign, credentials, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
prepareRequest(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set() } = {}) {
|
||||||
|
unsignableHeaders.add("content-type");
|
||||||
|
Object.keys(requestToSign.headers).map((header) => header.toLowerCase()).filter((header) => header.startsWith("x-amz-server-side-encryption")).forEach((header) => {
|
||||||
|
unhoistableHeaders.add(header);
|
||||||
|
});
|
||||||
|
requestToSign.headers[SHA256_HEADER] = UNSIGNED_PAYLOAD;
|
||||||
|
const currentHostHeader = requestToSign.headers.host;
|
||||||
|
const port = requestToSign.port;
|
||||||
|
const expectedHostHeader = `${requestToSign.hostname}${requestToSign.port != null ? ":" + port : ""}`;
|
||||||
|
if (!currentHostHeader || currentHostHeader === requestToSign.hostname && requestToSign.port != null) {
|
||||||
|
requestToSign.headers.host = expectedHostHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_S3RequestPresigner, "S3RequestPresigner");
|
||||||
|
var S3RequestPresigner = _S3RequestPresigner;
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var getSignedUrl = /* @__PURE__ */ __name(async (client, command, options = {}) => {
|
||||||
|
var _a, _b, _c;
|
||||||
|
let s3Presigner;
|
||||||
|
let region;
|
||||||
|
if (typeof client.config.endpointProvider === "function") {
|
||||||
|
const endpointV2 = await (0, import_middleware_endpoint.getEndpointFromInstructions)(
|
||||||
|
command.input,
|
||||||
|
command.constructor,
|
||||||
|
client.config
|
||||||
|
);
|
||||||
|
const authScheme = (_b = (_a = endpointV2.properties) == null ? void 0 : _a.authSchemes) == null ? void 0 : _b[0];
|
||||||
|
if ((authScheme == null ? void 0 : authScheme.name) === "sigv4a") {
|
||||||
|
region = (_c = authScheme == null ? void 0 : authScheme.signingRegionSet) == null ? void 0 : _c.join(",");
|
||||||
|
} else {
|
||||||
|
region = authScheme == null ? void 0 : authScheme.signingRegion;
|
||||||
|
}
|
||||||
|
s3Presigner = new S3RequestPresigner({
|
||||||
|
...client.config,
|
||||||
|
signingName: authScheme == null ? void 0 : authScheme.signingName,
|
||||||
|
region: async () => region
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
s3Presigner = new S3RequestPresigner(client.config);
|
||||||
|
}
|
||||||
|
const presignInterceptMiddleware = /* @__PURE__ */ __name((next, context) => async (args) => {
|
||||||
|
const { request } = args;
|
||||||
|
if (!import_protocol_http.HttpRequest.isInstance(request)) {
|
||||||
|
throw new Error("Request to be presigned is not an valid HTTP request.");
|
||||||
|
}
|
||||||
|
delete request.headers["amz-sdk-invocation-id"];
|
||||||
|
delete request.headers["amz-sdk-request"];
|
||||||
|
delete request.headers["x-amz-user-agent"];
|
||||||
|
let presigned2;
|
||||||
|
const presignerOptions = {
|
||||||
|
...options,
|
||||||
|
signingRegion: options.signingRegion ?? context["signing_region"] ?? region,
|
||||||
|
signingService: options.signingService ?? context["signing_service"]
|
||||||
|
};
|
||||||
|
if (context.s3ExpressIdentity) {
|
||||||
|
presigned2 = await s3Presigner.presignWithCredentials(request, context.s3ExpressIdentity, presignerOptions);
|
||||||
|
} else {
|
||||||
|
presigned2 = await s3Presigner.presign(request, presignerOptions);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
// Intercept the middleware stack by returning fake response
|
||||||
|
response: {},
|
||||||
|
output: {
|
||||||
|
$metadata: { httpStatusCode: 200 },
|
||||||
|
presigned: presigned2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, "presignInterceptMiddleware");
|
||||||
|
const middlewareName = "presignInterceptMiddleware";
|
||||||
|
const clientStack = client.middlewareStack.clone();
|
||||||
|
clientStack.addRelativeTo(presignInterceptMiddleware, {
|
||||||
|
name: middlewareName,
|
||||||
|
relation: "before",
|
||||||
|
toMiddleware: "awsAuthMiddleware",
|
||||||
|
override: true
|
||||||
|
});
|
||||||
|
const handler = command.resolveMiddleware(clientStack, client.config, {});
|
||||||
|
const { output } = await handler({ input: command.input });
|
||||||
|
const { presigned } = output;
|
||||||
|
return (0, import_util_format_url.formatUrl)(presigned);
|
||||||
|
}, "getSignedUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 1856:
|
/***/ 1856:
|
||||||
|
|
@ -28054,6 +28699,72 @@ import_util_endpoints.customEndpointFunctions.aws = awsEndpointFunctions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7053:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
formatUrl: () => formatUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
var import_querystring_builder = __nccwpck_require__(8031);
|
||||||
|
function formatUrl(request) {
|
||||||
|
const { port, query } = request;
|
||||||
|
let { protocol, path, hostname } = request;
|
||||||
|
if (protocol && protocol.slice(-1) !== ":") {
|
||||||
|
protocol += ":";
|
||||||
|
}
|
||||||
|
if (port) {
|
||||||
|
hostname += `:${port}`;
|
||||||
|
}
|
||||||
|
if (path && path.charAt(0) !== "/") {
|
||||||
|
path = `/${path}`;
|
||||||
|
}
|
||||||
|
let queryString = query ? (0, import_querystring_builder.buildQueryString)(query) : "";
|
||||||
|
if (queryString && queryString[0] !== "?") {
|
||||||
|
queryString = `?${queryString}`;
|
||||||
|
}
|
||||||
|
let auth = "";
|
||||||
|
if (request.username != null || request.password != null) {
|
||||||
|
const username = request.username ?? "";
|
||||||
|
const password = request.password ?? "";
|
||||||
|
auth = `${username}:${password}@`;
|
||||||
|
}
|
||||||
|
let fragment = "";
|
||||||
|
if (request.fragment) {
|
||||||
|
fragment = `#${request.fragment}`;
|
||||||
|
}
|
||||||
|
return `${protocol}//${auth}${hostname}${path}${queryString}${fragment}`;
|
||||||
|
}
|
||||||
|
__name(formatUrl, "formatUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 8095:
|
/***/ 8095:
|
||||||
|
|
@ -66451,6 +67162,92 @@ exports.VERSION = void 0;
|
||||||
exports.VERSION = '1.4.0';
|
exports.VERSION = '1.4.0';
|
||||||
//# sourceMappingURL=version.js.map
|
//# sourceMappingURL=version.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7020:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
AbortController: () => AbortController,
|
||||||
|
AbortHandler: () => import_types.AbortHandler,
|
||||||
|
AbortSignal: () => AbortSignal,
|
||||||
|
IAbortController: () => import_types.AbortController,
|
||||||
|
IAbortSignal: () => import_types.AbortSignal
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
|
||||||
|
|
||||||
|
// src/AbortSignal.ts
|
||||||
|
var import_types = __nccwpck_require__(5756);
|
||||||
|
var _AbortSignal = class _AbortSignal {
|
||||||
|
constructor() {
|
||||||
|
this.onabort = null;
|
||||||
|
this._aborted = false;
|
||||||
|
Object.defineProperty(this, "_aborted", {
|
||||||
|
value: false,
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether the associated operation has already been cancelled.
|
||||||
|
*/
|
||||||
|
get aborted() {
|
||||||
|
return this._aborted;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
abort() {
|
||||||
|
this._aborted = true;
|
||||||
|
if (this.onabort) {
|
||||||
|
this.onabort(this);
|
||||||
|
this.onabort = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortSignal, "AbortSignal");
|
||||||
|
var AbortSignal = _AbortSignal;
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
var _AbortController = class _AbortController {
|
||||||
|
constructor() {
|
||||||
|
this.signal = new AbortSignal();
|
||||||
|
}
|
||||||
|
abort() {
|
||||||
|
this.signal.abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortController, "AbortController");
|
||||||
|
var AbortController = _AbortController;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 3098:
|
/***/ 3098:
|
||||||
|
|
@ -92969,12 +93766,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
||||||
const client_s3_1 = __nccwpck_require__(9250);
|
const client_s3_1 = __nccwpck_require__(9250);
|
||||||
const child_process_1 = __nccwpck_require__(2081);
|
const { getSignedUrl } = __nccwpck_require__(5052);
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
const crypto = __importStar(__nccwpck_require__(6113));
|
const crypto = __importStar(__nccwpck_require__(6113));
|
||||||
|
const options_1 = __nccwpck_require__(6215);
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const utils = __importStar(__nccwpck_require__(1518));
|
const utils = __importStar(__nccwpck_require__(1518));
|
||||||
|
const lib_storage_1 = __nccwpck_require__(3087);
|
||||||
|
const downloadUtils_1 = __nccwpck_require__(6968);
|
||||||
const versionSalt = "1.0";
|
const versionSalt = "1.0";
|
||||||
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
||||||
|
const region = process.env.RUNS_ON_AWS_REGION ||
|
||||||
|
process.env.AWS_REGION ||
|
||||||
|
process.env.AWS_DEFAULT_REGION;
|
||||||
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
||||||
// don't pass changes upstream
|
// don't pass changes upstream
|
||||||
const components = paths.slice();
|
const components = paths.slice();
|
||||||
|
|
@ -92995,31 +93799,33 @@ function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false)
|
||||||
.digest("hex");
|
.digest("hex");
|
||||||
}
|
}
|
||||||
exports.getCacheVersion = getCacheVersion;
|
exports.getCacheVersion = getCacheVersion;
|
||||||
function getCacheEntryS3Key(restoreKey, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getS3Prefix(paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
const repository = process.env.GITHUB_REPOSITORY;
|
const repository = process.env.GITHUB_REPOSITORY;
|
||||||
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
||||||
return ["cache", repository, version, restoreKey].join("/");
|
return ["cache", repository, version].join("/");
|
||||||
}
|
}
|
||||||
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const cacheEntry = {};
|
const cacheEntry = {};
|
||||||
const s3Client = new client_s3_1.S3Client();
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
// Find the most recent key matching one of the restoreKeys prefixes
|
// Find the most recent key matching one of the restoreKeys prefixes
|
||||||
for (const restoreKey of keys) {
|
for (const restoreKey of keys) {
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
|
compressionMethod,
|
||||||
|
enableCrossOsArchive
|
||||||
|
});
|
||||||
const listObjectsParams = {
|
const listObjectsParams = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Prefix: getCacheEntryS3Key(restoreKey, paths, {
|
Prefix: [s3Prefix, restoreKey].join("/")
|
||||||
compressionMethod,
|
|
||||||
enableCrossOsArchive
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
||||||
if (Contents.length > 0) {
|
if (Contents.length > 0) {
|
||||||
// Sort keys by LastModified time in descending order
|
// Sort keys by LastModified time in descending order
|
||||||
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
||||||
cacheEntry.cacheKey = sortedKeys[0].Key; // Return the most recent key
|
const s3Path = sortedKeys[0].Key; // Return the most recent key
|
||||||
cacheEntry.archiveLocation = `s3://${bucketName}/${cacheEntry.cacheKey}`;
|
cacheEntry.cacheKey = s3Path === null || s3Path === void 0 ? void 0 : s3Path.replace(`${s3Prefix}/`, "");
|
||||||
|
cacheEntry.archiveLocation = `s3://${bucketName}/${s3Path}`;
|
||||||
return cacheEntry;
|
return cacheEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93027,7 +93833,6 @@ function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive })
|
||||||
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`No matching keys found in bucket ${bucketName}`);
|
|
||||||
return cacheEntry; // No keys found
|
return cacheEntry; // No keys found
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -93037,26 +93842,21 @@ function downloadCache(archiveLocation, archivePath, options) {
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const downloadProcess = (0, child_process_1.spawn)("aws", [
|
if (!region) {
|
||||||
"s3",
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
"cp",
|
}
|
||||||
archiveLocation,
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
archivePath
|
const archiveUrl = new URL(archiveLocation);
|
||||||
]);
|
const objectKey = archiveUrl.pathname.slice(1);
|
||||||
return new Promise((resolve, reject) => {
|
const command = new client_s3_1.GetObjectCommand({
|
||||||
downloadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
Bucket: bucketName,
|
||||||
downloadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
Key: objectKey
|
||||||
downloadProcess.on("close", code => {
|
|
||||||
if (code === 0) {
|
|
||||||
console.log(`File downloaded successfully from ${archiveLocation} to ${archivePath}`);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(`File download failed with code ${code}`);
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
const url = yield getSignedUrl(s3Client, command, {
|
||||||
|
expiresIn: 3600
|
||||||
|
});
|
||||||
|
const downloadOptions = (0, options_1.getDownloadOptions)(Object.assign(Object.assign({}, options), { downloadConcurrency: 14, concurrentBlobDownloads: true }));
|
||||||
|
yield (0, downloadUtils_1.downloadCacheHttpClientConcurrent)(url, archivePath, downloadOptions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.downloadCache = downloadCache;
|
exports.downloadCache = downloadCache;
|
||||||
|
|
@ -93065,33 +93865,36 @@ function saveCache(key, paths, archivePath, { compressionMethod, enableCrossOsAr
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const s3Key = getCacheEntryS3Key(key, paths, {
|
if (!region) {
|
||||||
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
|
}
|
||||||
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
compressionMethod,
|
compressionMethod,
|
||||||
enableCrossOsArchive
|
enableCrossOsArchive
|
||||||
});
|
});
|
||||||
const archiveLocation = `s3://${bucketName}/${s3Key}`;
|
const s3Key = `${s3Prefix}/${key}`;
|
||||||
const uploadProcess = (0, child_process_1.spawn)("aws", [
|
const multipartUpload = new lib_storage_1.Upload({
|
||||||
"s3",
|
client: s3Client,
|
||||||
"cp",
|
params: {
|
||||||
archivePath,
|
Bucket: bucketName,
|
||||||
archiveLocation
|
Key: s3Key,
|
||||||
]);
|
Body: (0, fs_1.createReadStream)(archivePath)
|
||||||
|
},
|
||||||
|
// Part size in bytes
|
||||||
|
partSize: 32 * 1024 * 1024,
|
||||||
|
// Max concurrency
|
||||||
|
queueSize: 14
|
||||||
|
});
|
||||||
// Commit Cache
|
// Commit Cache
|
||||||
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||||
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
||||||
const code = yield new Promise((resolve, reject) => {
|
core.info(`Uploading cache from ${archivePath} to ${bucketName}/${s3Key}`);
|
||||||
uploadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
multipartUpload.on("httpUploadProgress", progress => {
|
||||||
uploadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
core.info(`Uploaded ${progress.part}/${progress.total}.`);
|
||||||
uploadProcess.on("close", code => {
|
|
||||||
resolve(code);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
if (code === 0) {
|
yield multipartUpload.done();
|
||||||
core.info(`Cache saved successfully.`);
|
core.info(`Cache saved successfully.`);
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`File upload failed with code ${code}.`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
@ -93324,6 +94127,283 @@ function saveCache(paths, key, options, enableCrossOsArchive = false) {
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 6968:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.downloadCacheHttpClientConcurrent = exports.DownloadProgress = void 0;
|
||||||
|
// Just a copy of the original file from the toolkit/actions/cache repository, with a change for byte range used in the downloadCacheHttpClientConcurrent function.
|
||||||
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
|
const http_client_1 = __nccwpck_require__(6255);
|
||||||
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
|
const requestUtils_1 = __nccwpck_require__(3981);
|
||||||
|
/**
|
||||||
|
* Class for tracking the download state and displaying stats.
|
||||||
|
*/
|
||||||
|
class DownloadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.segmentIndex = 0;
|
||||||
|
this.segmentSize = 0;
|
||||||
|
this.segmentOffset = 0;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Progress to the next segment. Only call this method when the previous segment
|
||||||
|
* is complete.
|
||||||
|
*
|
||||||
|
* @param segmentSize the length of the next segment
|
||||||
|
*/
|
||||||
|
nextSegment(segmentSize) {
|
||||||
|
this.segmentOffset = this.segmentOffset + this.segmentSize;
|
||||||
|
this.segmentIndex = this.segmentIndex + 1;
|
||||||
|
this.segmentSize = segmentSize;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
core.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes received for the current segment.
|
||||||
|
*
|
||||||
|
* @param receivedBytes the number of bytes received
|
||||||
|
*/
|
||||||
|
setReceivedBytes(receivedBytes) {
|
||||||
|
this.receivedBytes = receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.segmentOffset + this.receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the download is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current download stats. Once the download completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.segmentOffset + this.receivedBytes;
|
||||||
|
const percentage = (100 *
|
||||||
|
(transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const downloadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setReceivedBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the download
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.DownloadProgress = DownloadProgress;
|
||||||
|
/**
|
||||||
|
* Download the cache using the Actions toolkit http-client concurrently
|
||||||
|
*
|
||||||
|
* @param archiveLocation the URL for the cache
|
||||||
|
* @param archivePath the local path where the cache is saved
|
||||||
|
*/
|
||||||
|
function downloadCacheHttpClientConcurrent(archiveLocation, archivePath, options) {
|
||||||
|
var _a;
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const archiveDescriptor = yield fs.promises.open(archivePath, "w");
|
||||||
|
const httpClient = new http_client_1.HttpClient("actions/cache", undefined, {
|
||||||
|
socketTimeout: options.timeoutInMs,
|
||||||
|
keepAlive: true
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const res = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCacheMetadata", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.request("GET", archiveLocation, null, {
|
||||||
|
Range: "bytes=0-1"
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
const contentRange = res.message.headers["content-range"];
|
||||||
|
if (!contentRange) {
|
||||||
|
throw new Error("Range request not supported by server");
|
||||||
|
}
|
||||||
|
const match = contentRange === null || contentRange === void 0 ? void 0 : contentRange.match(/bytes \d+-\d+\/(\d+)/);
|
||||||
|
if (!match) {
|
||||||
|
throw new Error("Content-Range header in server response not in correct format");
|
||||||
|
}
|
||||||
|
const length = parseInt(match[1]);
|
||||||
|
if (Number.isNaN(length)) {
|
||||||
|
throw new Error(`Could not interpret Content-Length: ${length}`);
|
||||||
|
}
|
||||||
|
const downloads = [];
|
||||||
|
const blockSize = 32 * 1024 * 1024;
|
||||||
|
for (let offset = 0; offset < length; offset += blockSize) {
|
||||||
|
const count = Math.min(blockSize, length - offset);
|
||||||
|
downloads.push({
|
||||||
|
offset,
|
||||||
|
promiseGetter: () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield downloadSegmentRetry(httpClient, archiveLocation, offset, count);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// reverse to use .pop instead of .shift
|
||||||
|
downloads.reverse();
|
||||||
|
let actives = 0;
|
||||||
|
let bytesDownloaded = 0;
|
||||||
|
const progress = new DownloadProgress(length);
|
||||||
|
progress.startDisplayTimer();
|
||||||
|
const progressFn = progress.onProgress();
|
||||||
|
const activeDownloads = [];
|
||||||
|
let nextDownload;
|
||||||
|
const waitAndWrite = () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const segment = yield Promise.race(Object.values(activeDownloads));
|
||||||
|
yield archiveDescriptor.write(segment.buffer, 0, segment.count, segment.offset);
|
||||||
|
actives--;
|
||||||
|
delete activeDownloads[segment.offset];
|
||||||
|
bytesDownloaded += segment.count;
|
||||||
|
progressFn({ loadedBytes: bytesDownloaded });
|
||||||
|
});
|
||||||
|
while ((nextDownload = downloads.pop())) {
|
||||||
|
activeDownloads[nextDownload.offset] = nextDownload.promiseGetter();
|
||||||
|
actives++;
|
||||||
|
if (actives >= ((_a = options.downloadConcurrency) !== null && _a !== void 0 ? _a : 10)) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (actives > 0) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
httpClient.dispose();
|
||||||
|
yield archiveDescriptor.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent;
|
||||||
|
function downloadSegmentRetry(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const retries = 5;
|
||||||
|
let failures = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const timeout = 30000;
|
||||||
|
const result = yield promiseWithTimeout(timeout, downloadSegment(httpClient, archiveLocation, offset, count));
|
||||||
|
if (typeof result === "string") {
|
||||||
|
throw new Error("downloadSegmentRetry failed due to timeout");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (failures >= retries) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function downloadSegment(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const partRes = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCachePart", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.get(archiveLocation, {
|
||||||
|
Range: `bytes=${offset}-${offset + count - 1}`
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
if (!partRes.readBodyBuffer) {
|
||||||
|
throw new Error("Expected HttpClientResponse to implement readBodyBuffer");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
offset,
|
||||||
|
count,
|
||||||
|
buffer: yield partRes.readBodyBuffer()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const promiseWithTimeout = (timeoutMs, promise) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
|
let timeoutHandle;
|
||||||
|
const timeoutPromise = new Promise(resolve => {
|
||||||
|
timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
|
||||||
|
});
|
||||||
|
return Promise.race([promise, timeoutPromise]).then(result => {
|
||||||
|
clearTimeout(timeoutHandle);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 2357:
|
/***/ 2357:
|
||||||
|
|
|
||||||
|
|
@ -25009,6 +25009,481 @@ const client_sts_1 = __nccwpck_require__(2209);
|
||||||
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3087:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
Upload: () => Upload
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var import_client_s3 = __nccwpck_require__(9250);
|
||||||
|
var import_abort_controller = __nccwpck_require__(7020);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_smithy_client = __nccwpck_require__(3570);
|
||||||
|
var import_events = __nccwpck_require__(2361);
|
||||||
|
|
||||||
|
// src/bytelength.ts
|
||||||
|
var import_runtimeConfig = __nccwpck_require__(3407);
|
||||||
|
var byteLength = /* @__PURE__ */ __name((input) => {
|
||||||
|
if (input === null || input === void 0)
|
||||||
|
return 0;
|
||||||
|
if (typeof input === "string")
|
||||||
|
input = Buffer.from(input);
|
||||||
|
if (typeof input.byteLength === "number") {
|
||||||
|
return input.byteLength;
|
||||||
|
} else if (typeof input.length === "number") {
|
||||||
|
return input.length;
|
||||||
|
} else if (typeof input.size === "number") {
|
||||||
|
return input.size;
|
||||||
|
} else if (typeof input.path === "string") {
|
||||||
|
try {
|
||||||
|
return import_runtimeConfig.ClientDefaultValues.lstatSync(input.path).size;
|
||||||
|
} catch (error) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return void 0;
|
||||||
|
}, "byteLength");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
|
||||||
|
var import_stream = __nccwpck_require__(2781);
|
||||||
|
|
||||||
|
// src/chunks/getChunkBuffer.ts
|
||||||
|
async function* getChunkBuffer(data, partSize) {
|
||||||
|
let partNumber = 1;
|
||||||
|
let startByte = 0;
|
||||||
|
let endByte = partSize;
|
||||||
|
while (endByte < data.byteLength) {
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte, endByte)
|
||||||
|
};
|
||||||
|
partNumber += 1;
|
||||||
|
startByte = endByte;
|
||||||
|
endByte = startByte + partSize;
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkBuffer, "getChunkBuffer");
|
||||||
|
|
||||||
|
// src/chunks/getChunkStream.ts
|
||||||
|
var import_buffer = __nccwpck_require__(4300);
|
||||||
|
async function* getChunkStream(data, partSize, getNextData) {
|
||||||
|
let partNumber = 1;
|
||||||
|
const currentBuffer = { chunks: [], length: 0 };
|
||||||
|
for await (const datum of getNextData(data)) {
|
||||||
|
currentBuffer.chunks.push(datum);
|
||||||
|
currentBuffer.length += datum.length;
|
||||||
|
while (currentBuffer.length >= partSize) {
|
||||||
|
const dataChunk = currentBuffer.chunks.length > 1 ? import_buffer.Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0];
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: dataChunk.slice(0, partSize)
|
||||||
|
};
|
||||||
|
currentBuffer.chunks = [dataChunk.slice(partSize)];
|
||||||
|
currentBuffer.length = currentBuffer.chunks[0].length;
|
||||||
|
partNumber += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: import_buffer.Buffer.concat(currentBuffer.chunks),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkStream, "getChunkStream");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadable.ts
|
||||||
|
|
||||||
|
async function* getDataReadable(data) {
|
||||||
|
for await (const chunk of data) {
|
||||||
|
yield import_buffer.Buffer.from(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadable, "getDataReadable");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadableStream.ts
|
||||||
|
|
||||||
|
async function* getDataReadableStream(data) {
|
||||||
|
const reader = data.getReader();
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done)
|
||||||
|
return;
|
||||||
|
yield import_buffer.Buffer.from(value);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
reader.releaseLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadableStream, "getDataReadableStream");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
var getChunk = /* @__PURE__ */ __name((data, partSize) => {
|
||||||
|
if (data instanceof import_buffer.Buffer) {
|
||||||
|
return getChunkBuffer(data, partSize);
|
||||||
|
} else if (data instanceof import_stream.Readable) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadable);
|
||||||
|
} else if (data instanceof String || typeof data === "string" || data instanceof Uint8Array) {
|
||||||
|
return getChunkBuffer(import_buffer.Buffer.from(data), partSize);
|
||||||
|
}
|
||||||
|
if (typeof data.stream === "function") {
|
||||||
|
return getChunkStream(data.stream(), partSize, getDataReadableStream);
|
||||||
|
} else if (data instanceof ReadableStream) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadableStream);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
"Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, "getChunk");
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var MIN_PART_SIZE = 1024 * 1024 * 5;
|
||||||
|
var _Upload = class _Upload extends import_events.EventEmitter {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
/**
|
||||||
|
* S3 multipart upload does not allow more than 10000 parts.
|
||||||
|
*/
|
||||||
|
this.MAX_PARTS = 1e4;
|
||||||
|
// Defaults.
|
||||||
|
this.queueSize = 4;
|
||||||
|
this.partSize = MIN_PART_SIZE;
|
||||||
|
this.leavePartsOnError = false;
|
||||||
|
this.tags = [];
|
||||||
|
this.concurrentUploaders = [];
|
||||||
|
this.uploadedParts = [];
|
||||||
|
this.isMultiPart = true;
|
||||||
|
this.queueSize = options.queueSize || this.queueSize;
|
||||||
|
this.partSize = options.partSize || this.partSize;
|
||||||
|
this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
|
||||||
|
this.tags = options.tags || this.tags;
|
||||||
|
this.client = options.client;
|
||||||
|
this.params = options.params;
|
||||||
|
this.__validateInput();
|
||||||
|
this.totalBytes = byteLength(this.params.Body);
|
||||||
|
this.bytesUploadedSoFar = 0;
|
||||||
|
this.abortController = options.abortController ?? new import_abort_controller.AbortController();
|
||||||
|
}
|
||||||
|
async abort() {
|
||||||
|
this.abortController.abort();
|
||||||
|
}
|
||||||
|
async done() {
|
||||||
|
return await Promise.race([this.__doMultipartUpload(), this.__abortTimeout(this.abortController.signal)]);
|
||||||
|
}
|
||||||
|
on(event, listener) {
|
||||||
|
this.uploadEvent = event;
|
||||||
|
return super.on(event, listener);
|
||||||
|
}
|
||||||
|
async __uploadUsingPut(dataPart) {
|
||||||
|
var _a;
|
||||||
|
this.isMultiPart = false;
|
||||||
|
const params = { ...this.params, Body: dataPart.data };
|
||||||
|
const clientConfig = this.client.config;
|
||||||
|
const requestHandler = clientConfig.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event) => {
|
||||||
|
this.bytesUploadedSoFar = event.loaded;
|
||||||
|
this.totalBytes = event.total;
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const resolved = await Promise.all([this.client.send(new import_client_s3.PutObjectCommand(params)), (_a = clientConfig == null ? void 0 : clientConfig.endpoint) == null ? void 0 : _a.call(clientConfig)]);
|
||||||
|
const putResult = resolved[0];
|
||||||
|
let endpoint = resolved[1];
|
||||||
|
if (!endpoint) {
|
||||||
|
endpoint = (0, import_middleware_endpoint.toEndpointV1)(
|
||||||
|
await (0, import_middleware_endpoint.getEndpointFromInstructions)(params, import_client_s3.PutObjectCommand, {
|
||||||
|
...clientConfig
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!endpoint) {
|
||||||
|
throw new Error('Could not resolve endpoint from S3 "client.config.endpoint()" nor EndpointsV2.');
|
||||||
|
}
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const locationKey = this.params.Key.split("/").map((segment) => (0, import_smithy_client.extendedEncodeURIComponent)(segment)).join("/");
|
||||||
|
const locationBucket = (0, import_smithy_client.extendedEncodeURIComponent)(this.params.Bucket);
|
||||||
|
const Location = (() => {
|
||||||
|
const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`);
|
||||||
|
const forcePathStyle = this.client.config.forcePathStyle;
|
||||||
|
if (forcePathStyle) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationBucket}/${locationKey}`;
|
||||||
|
}
|
||||||
|
if (endpointHostnameIncludesBucket) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationKey}`;
|
||||||
|
}
|
||||||
|
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}/${locationKey}`;
|
||||||
|
})();
|
||||||
|
this.singleUploadResult = {
|
||||||
|
...putResult,
|
||||||
|
Bucket: this.params.Bucket,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Location
|
||||||
|
};
|
||||||
|
const totalSize = byteLength(dataPart.data);
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: totalSize,
|
||||||
|
total: totalSize,
|
||||||
|
part: 1,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async __createMultipartUpload() {
|
||||||
|
if (!this.createMultiPartPromise) {
|
||||||
|
const createCommandParams = { ...this.params, Body: void 0 };
|
||||||
|
this.createMultiPartPromise = this.client.send(new import_client_s3.CreateMultipartUploadCommand(createCommandParams));
|
||||||
|
}
|
||||||
|
return this.createMultiPartPromise;
|
||||||
|
}
|
||||||
|
async __doConcurrentUpload(dataFeeder) {
|
||||||
|
for await (const dataPart of dataFeeder) {
|
||||||
|
if (this.uploadedParts.length > this.MAX_PARTS) {
|
||||||
|
throw new Error(
|
||||||
|
`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.params.Key} and ${this.params.Bucket}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dataPart.partNumber === 1 && dataPart.lastPart) {
|
||||||
|
return await this.__uploadUsingPut(dataPart);
|
||||||
|
}
|
||||||
|
if (!this.uploadId) {
|
||||||
|
const { UploadId } = await this.__createMultipartUpload();
|
||||||
|
this.uploadId = UploadId;
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const partSize = byteLength(dataPart.data) || 0;
|
||||||
|
const requestHandler = this.client.config.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
let lastSeenBytes = 0;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event, request) => {
|
||||||
|
const requestPartSize = Number(request.query["partNumber"]) || -1;
|
||||||
|
if (requestPartSize !== dataPart.partNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.total && partSize) {
|
||||||
|
this.bytesUploadedSoFar += event.loaded - lastSeenBytes;
|
||||||
|
lastSeenBytes = event.loaded;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const partResult = await this.client.send(
|
||||||
|
new import_client_s3.UploadPartCommand({
|
||||||
|
...this.params,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
Body: dataPart.data,
|
||||||
|
PartNumber: dataPart.partNumber
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!partResult.ETag) {
|
||||||
|
throw new Error(
|
||||||
|
`Part ${dataPart.partNumber} is missing ETag in UploadPart response. Missing Bucket CORS configuration for ETag header?`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.uploadedParts.push({
|
||||||
|
PartNumber: dataPart.partNumber,
|
||||||
|
ETag: partResult.ETag,
|
||||||
|
...partResult.ChecksumCRC32 && { ChecksumCRC32: partResult.ChecksumCRC32 },
|
||||||
|
...partResult.ChecksumCRC32C && { ChecksumCRC32C: partResult.ChecksumCRC32C },
|
||||||
|
...partResult.ChecksumSHA1 && { ChecksumSHA1: partResult.ChecksumSHA1 },
|
||||||
|
...partResult.ChecksumSHA256 && { ChecksumSHA256: partResult.ChecksumSHA256 }
|
||||||
|
});
|
||||||
|
if (eventEmitter === null) {
|
||||||
|
this.bytesUploadedSoFar += partSize;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (!this.uploadId) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (this.leavePartsOnError) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __doMultipartUpload() {
|
||||||
|
const dataFeeder = getChunk(this.params.Body, this.partSize);
|
||||||
|
for (let index = 0; index < this.queueSize; index++) {
|
||||||
|
const currentUpload = this.__doConcurrentUpload(dataFeeder);
|
||||||
|
this.concurrentUploaders.push(currentUpload);
|
||||||
|
}
|
||||||
|
await Promise.all(this.concurrentUploaders);
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
throw Object.assign(new Error("Upload aborted."), { name: "AbortError" });
|
||||||
|
}
|
||||||
|
let result;
|
||||||
|
if (this.isMultiPart) {
|
||||||
|
this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
|
||||||
|
const uploadCompleteParams = {
|
||||||
|
...this.params,
|
||||||
|
Body: void 0,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
MultipartUpload: {
|
||||||
|
Parts: this.uploadedParts
|
||||||
|
}
|
||||||
|
};
|
||||||
|
result = await this.client.send(new import_client_s3.CompleteMultipartUploadCommand(uploadCompleteParams));
|
||||||
|
if (typeof (result == null ? void 0 : result.Location) === "string" && result.Location.includes("%2F")) {
|
||||||
|
result.Location = result.Location.replace(/%2F/g, "/");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = this.singleUploadResult;
|
||||||
|
}
|
||||||
|
if (this.tags.length) {
|
||||||
|
await this.client.send(
|
||||||
|
new import_client_s3.PutObjectTaggingCommand({
|
||||||
|
...this.params,
|
||||||
|
Tagging: {
|
||||||
|
TagSet: this.tags
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
__notifyProgress(progress) {
|
||||||
|
if (this.uploadEvent) {
|
||||||
|
this.emit(this.uploadEvent, progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __abortTimeout(abortSignal) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
abortSignal.onabort = () => {
|
||||||
|
const abortError = new Error("Upload aborted.");
|
||||||
|
abortError.name = "AbortError";
|
||||||
|
reject(abortError);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
__validateInput() {
|
||||||
|
if (!this.params) {
|
||||||
|
throw new Error(`InputError: Upload requires params to be passed to upload.`);
|
||||||
|
}
|
||||||
|
if (!this.client) {
|
||||||
|
throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
|
||||||
|
}
|
||||||
|
if (this.partSize < MIN_PART_SIZE) {
|
||||||
|
throw new Error(
|
||||||
|
`EntityTooSmall: Your proposed upload partsize [${this.partSize}] is smaller than the minimum allowed size [${MIN_PART_SIZE}] (5MB)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.queueSize < 1) {
|
||||||
|
throw new Error(`Queue size: Must have at least one uploading queue.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_Upload, "Upload");
|
||||||
|
var Upload = _Upload;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3407:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientDefaultValues = void 0;
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
|
const runtimeConfig_shared_1 = __nccwpck_require__(9583);
|
||||||
|
exports.ClientDefaultValues = {
|
||||||
|
...runtimeConfig_shared_1.ClientSharedValues,
|
||||||
|
runtime: "node",
|
||||||
|
lstatSync: fs_1.lstatSync,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 9583:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientSharedValues = void 0;
|
||||||
|
exports.ClientSharedValues = {
|
||||||
|
lstatSync: () => { },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 6689:
|
/***/ 6689:
|
||||||
|
|
@ -27260,6 +27735,176 @@ var resolveRegionConfig = /* @__PURE__ */ __name((input) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5052:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
S3RequestPresigner: () => S3RequestPresigner,
|
||||||
|
getSignedUrl: () => getSignedUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var import_util_format_url = __nccwpck_require__(7053);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_protocol_http = __nccwpck_require__(9556);
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var import_signature_v4_multi_region = __nccwpck_require__(1856);
|
||||||
|
|
||||||
|
// src/constants.ts
|
||||||
|
var UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
|
||||||
|
var SHA256_HEADER = "X-Amz-Content-Sha256";
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var _S3RequestPresigner = class _S3RequestPresigner {
|
||||||
|
constructor(options) {
|
||||||
|
const resolvedOptions = {
|
||||||
|
// Allow `signingName` because we want to support usecase of supply client's resolved config
|
||||||
|
// directly. Where service equals signingName.
|
||||||
|
service: options.signingName || options.service || "s3",
|
||||||
|
uriEscapePath: options.uriEscapePath || false,
|
||||||
|
applyChecksum: options.applyChecksum || false,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
this.signer = new import_signature_v4_multi_region.SignatureV4MultiRegion(resolvedOptions);
|
||||||
|
}
|
||||||
|
presign(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presign(requestToSign, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
presignWithCredentials(requestToSign, credentials, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presignWithCredentials(requestToSign, credentials, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
prepareRequest(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set() } = {}) {
|
||||||
|
unsignableHeaders.add("content-type");
|
||||||
|
Object.keys(requestToSign.headers).map((header) => header.toLowerCase()).filter((header) => header.startsWith("x-amz-server-side-encryption")).forEach((header) => {
|
||||||
|
unhoistableHeaders.add(header);
|
||||||
|
});
|
||||||
|
requestToSign.headers[SHA256_HEADER] = UNSIGNED_PAYLOAD;
|
||||||
|
const currentHostHeader = requestToSign.headers.host;
|
||||||
|
const port = requestToSign.port;
|
||||||
|
const expectedHostHeader = `${requestToSign.hostname}${requestToSign.port != null ? ":" + port : ""}`;
|
||||||
|
if (!currentHostHeader || currentHostHeader === requestToSign.hostname && requestToSign.port != null) {
|
||||||
|
requestToSign.headers.host = expectedHostHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_S3RequestPresigner, "S3RequestPresigner");
|
||||||
|
var S3RequestPresigner = _S3RequestPresigner;
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var getSignedUrl = /* @__PURE__ */ __name(async (client, command, options = {}) => {
|
||||||
|
var _a, _b, _c;
|
||||||
|
let s3Presigner;
|
||||||
|
let region;
|
||||||
|
if (typeof client.config.endpointProvider === "function") {
|
||||||
|
const endpointV2 = await (0, import_middleware_endpoint.getEndpointFromInstructions)(
|
||||||
|
command.input,
|
||||||
|
command.constructor,
|
||||||
|
client.config
|
||||||
|
);
|
||||||
|
const authScheme = (_b = (_a = endpointV2.properties) == null ? void 0 : _a.authSchemes) == null ? void 0 : _b[0];
|
||||||
|
if ((authScheme == null ? void 0 : authScheme.name) === "sigv4a") {
|
||||||
|
region = (_c = authScheme == null ? void 0 : authScheme.signingRegionSet) == null ? void 0 : _c.join(",");
|
||||||
|
} else {
|
||||||
|
region = authScheme == null ? void 0 : authScheme.signingRegion;
|
||||||
|
}
|
||||||
|
s3Presigner = new S3RequestPresigner({
|
||||||
|
...client.config,
|
||||||
|
signingName: authScheme == null ? void 0 : authScheme.signingName,
|
||||||
|
region: async () => region
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
s3Presigner = new S3RequestPresigner(client.config);
|
||||||
|
}
|
||||||
|
const presignInterceptMiddleware = /* @__PURE__ */ __name((next, context) => async (args) => {
|
||||||
|
const { request } = args;
|
||||||
|
if (!import_protocol_http.HttpRequest.isInstance(request)) {
|
||||||
|
throw new Error("Request to be presigned is not an valid HTTP request.");
|
||||||
|
}
|
||||||
|
delete request.headers["amz-sdk-invocation-id"];
|
||||||
|
delete request.headers["amz-sdk-request"];
|
||||||
|
delete request.headers["x-amz-user-agent"];
|
||||||
|
let presigned2;
|
||||||
|
const presignerOptions = {
|
||||||
|
...options,
|
||||||
|
signingRegion: options.signingRegion ?? context["signing_region"] ?? region,
|
||||||
|
signingService: options.signingService ?? context["signing_service"]
|
||||||
|
};
|
||||||
|
if (context.s3ExpressIdentity) {
|
||||||
|
presigned2 = await s3Presigner.presignWithCredentials(request, context.s3ExpressIdentity, presignerOptions);
|
||||||
|
} else {
|
||||||
|
presigned2 = await s3Presigner.presign(request, presignerOptions);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
// Intercept the middleware stack by returning fake response
|
||||||
|
response: {},
|
||||||
|
output: {
|
||||||
|
$metadata: { httpStatusCode: 200 },
|
||||||
|
presigned: presigned2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, "presignInterceptMiddleware");
|
||||||
|
const middlewareName = "presignInterceptMiddleware";
|
||||||
|
const clientStack = client.middlewareStack.clone();
|
||||||
|
clientStack.addRelativeTo(presignInterceptMiddleware, {
|
||||||
|
name: middlewareName,
|
||||||
|
relation: "before",
|
||||||
|
toMiddleware: "awsAuthMiddleware",
|
||||||
|
override: true
|
||||||
|
});
|
||||||
|
const handler = command.resolveMiddleware(clientStack, client.config, {});
|
||||||
|
const { output } = await handler({ input: command.input });
|
||||||
|
const { presigned } = output;
|
||||||
|
return (0, import_util_format_url.formatUrl)(presigned);
|
||||||
|
}, "getSignedUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 1856:
|
/***/ 1856:
|
||||||
|
|
@ -28054,6 +28699,72 @@ import_util_endpoints.customEndpointFunctions.aws = awsEndpointFunctions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7053:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
formatUrl: () => formatUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
var import_querystring_builder = __nccwpck_require__(8031);
|
||||||
|
function formatUrl(request) {
|
||||||
|
const { port, query } = request;
|
||||||
|
let { protocol, path, hostname } = request;
|
||||||
|
if (protocol && protocol.slice(-1) !== ":") {
|
||||||
|
protocol += ":";
|
||||||
|
}
|
||||||
|
if (port) {
|
||||||
|
hostname += `:${port}`;
|
||||||
|
}
|
||||||
|
if (path && path.charAt(0) !== "/") {
|
||||||
|
path = `/${path}`;
|
||||||
|
}
|
||||||
|
let queryString = query ? (0, import_querystring_builder.buildQueryString)(query) : "";
|
||||||
|
if (queryString && queryString[0] !== "?") {
|
||||||
|
queryString = `?${queryString}`;
|
||||||
|
}
|
||||||
|
let auth = "";
|
||||||
|
if (request.username != null || request.password != null) {
|
||||||
|
const username = request.username ?? "";
|
||||||
|
const password = request.password ?? "";
|
||||||
|
auth = `${username}:${password}@`;
|
||||||
|
}
|
||||||
|
let fragment = "";
|
||||||
|
if (request.fragment) {
|
||||||
|
fragment = `#${request.fragment}`;
|
||||||
|
}
|
||||||
|
return `${protocol}//${auth}${hostname}${path}${queryString}${fragment}`;
|
||||||
|
}
|
||||||
|
__name(formatUrl, "formatUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 8095:
|
/***/ 8095:
|
||||||
|
|
@ -66451,6 +67162,92 @@ exports.VERSION = void 0;
|
||||||
exports.VERSION = '1.4.0';
|
exports.VERSION = '1.4.0';
|
||||||
//# sourceMappingURL=version.js.map
|
//# sourceMappingURL=version.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7020:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
AbortController: () => AbortController,
|
||||||
|
AbortHandler: () => import_types.AbortHandler,
|
||||||
|
AbortSignal: () => AbortSignal,
|
||||||
|
IAbortController: () => import_types.AbortController,
|
||||||
|
IAbortSignal: () => import_types.AbortSignal
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
|
||||||
|
|
||||||
|
// src/AbortSignal.ts
|
||||||
|
var import_types = __nccwpck_require__(5756);
|
||||||
|
var _AbortSignal = class _AbortSignal {
|
||||||
|
constructor() {
|
||||||
|
this.onabort = null;
|
||||||
|
this._aborted = false;
|
||||||
|
Object.defineProperty(this, "_aborted", {
|
||||||
|
value: false,
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether the associated operation has already been cancelled.
|
||||||
|
*/
|
||||||
|
get aborted() {
|
||||||
|
return this._aborted;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
abort() {
|
||||||
|
this._aborted = true;
|
||||||
|
if (this.onabort) {
|
||||||
|
this.onabort(this);
|
||||||
|
this.onabort = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortSignal, "AbortSignal");
|
||||||
|
var AbortSignal = _AbortSignal;
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
var _AbortController = class _AbortController {
|
||||||
|
constructor() {
|
||||||
|
this.signal = new AbortSignal();
|
||||||
|
}
|
||||||
|
abort() {
|
||||||
|
this.signal.abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortController, "AbortController");
|
||||||
|
var AbortController = _AbortController;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 3098:
|
/***/ 3098:
|
||||||
|
|
@ -92969,12 +93766,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
||||||
const client_s3_1 = __nccwpck_require__(9250);
|
const client_s3_1 = __nccwpck_require__(9250);
|
||||||
const child_process_1 = __nccwpck_require__(2081);
|
const { getSignedUrl } = __nccwpck_require__(5052);
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
const crypto = __importStar(__nccwpck_require__(6113));
|
const crypto = __importStar(__nccwpck_require__(6113));
|
||||||
|
const options_1 = __nccwpck_require__(6215);
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const utils = __importStar(__nccwpck_require__(1518));
|
const utils = __importStar(__nccwpck_require__(1518));
|
||||||
|
const lib_storage_1 = __nccwpck_require__(3087);
|
||||||
|
const downloadUtils_1 = __nccwpck_require__(6968);
|
||||||
const versionSalt = "1.0";
|
const versionSalt = "1.0";
|
||||||
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
||||||
|
const region = process.env.RUNS_ON_AWS_REGION ||
|
||||||
|
process.env.AWS_REGION ||
|
||||||
|
process.env.AWS_DEFAULT_REGION;
|
||||||
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
||||||
// don't pass changes upstream
|
// don't pass changes upstream
|
||||||
const components = paths.slice();
|
const components = paths.slice();
|
||||||
|
|
@ -92995,31 +93799,33 @@ function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false)
|
||||||
.digest("hex");
|
.digest("hex");
|
||||||
}
|
}
|
||||||
exports.getCacheVersion = getCacheVersion;
|
exports.getCacheVersion = getCacheVersion;
|
||||||
function getCacheEntryS3Key(restoreKey, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getS3Prefix(paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
const repository = process.env.GITHUB_REPOSITORY;
|
const repository = process.env.GITHUB_REPOSITORY;
|
||||||
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
||||||
return ["cache", repository, version, restoreKey].join("/");
|
return ["cache", repository, version].join("/");
|
||||||
}
|
}
|
||||||
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const cacheEntry = {};
|
const cacheEntry = {};
|
||||||
const s3Client = new client_s3_1.S3Client();
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
// Find the most recent key matching one of the restoreKeys prefixes
|
// Find the most recent key matching one of the restoreKeys prefixes
|
||||||
for (const restoreKey of keys) {
|
for (const restoreKey of keys) {
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
|
compressionMethod,
|
||||||
|
enableCrossOsArchive
|
||||||
|
});
|
||||||
const listObjectsParams = {
|
const listObjectsParams = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Prefix: getCacheEntryS3Key(restoreKey, paths, {
|
Prefix: [s3Prefix, restoreKey].join("/")
|
||||||
compressionMethod,
|
|
||||||
enableCrossOsArchive
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
||||||
if (Contents.length > 0) {
|
if (Contents.length > 0) {
|
||||||
// Sort keys by LastModified time in descending order
|
// Sort keys by LastModified time in descending order
|
||||||
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
||||||
cacheEntry.cacheKey = sortedKeys[0].Key; // Return the most recent key
|
const s3Path = sortedKeys[0].Key; // Return the most recent key
|
||||||
cacheEntry.archiveLocation = `s3://${bucketName}/${cacheEntry.cacheKey}`;
|
cacheEntry.cacheKey = s3Path === null || s3Path === void 0 ? void 0 : s3Path.replace(`${s3Prefix}/`, "");
|
||||||
|
cacheEntry.archiveLocation = `s3://${bucketName}/${s3Path}`;
|
||||||
return cacheEntry;
|
return cacheEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93027,7 +93833,6 @@ function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive })
|
||||||
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`No matching keys found in bucket ${bucketName}`);
|
|
||||||
return cacheEntry; // No keys found
|
return cacheEntry; // No keys found
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -93037,26 +93842,21 @@ function downloadCache(archiveLocation, archivePath, options) {
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const downloadProcess = (0, child_process_1.spawn)("aws", [
|
if (!region) {
|
||||||
"s3",
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
"cp",
|
}
|
||||||
archiveLocation,
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
archivePath
|
const archiveUrl = new URL(archiveLocation);
|
||||||
]);
|
const objectKey = archiveUrl.pathname.slice(1);
|
||||||
return new Promise((resolve, reject) => {
|
const command = new client_s3_1.GetObjectCommand({
|
||||||
downloadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
Bucket: bucketName,
|
||||||
downloadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
Key: objectKey
|
||||||
downloadProcess.on("close", code => {
|
|
||||||
if (code === 0) {
|
|
||||||
console.log(`File downloaded successfully from ${archiveLocation} to ${archivePath}`);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(`File download failed with code ${code}`);
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
const url = yield getSignedUrl(s3Client, command, {
|
||||||
|
expiresIn: 3600
|
||||||
|
});
|
||||||
|
const downloadOptions = (0, options_1.getDownloadOptions)(Object.assign(Object.assign({}, options), { downloadConcurrency: 14, concurrentBlobDownloads: true }));
|
||||||
|
yield (0, downloadUtils_1.downloadCacheHttpClientConcurrent)(url, archivePath, downloadOptions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.downloadCache = downloadCache;
|
exports.downloadCache = downloadCache;
|
||||||
|
|
@ -93065,33 +93865,36 @@ function saveCache(key, paths, archivePath, { compressionMethod, enableCrossOsAr
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const s3Key = getCacheEntryS3Key(key, paths, {
|
if (!region) {
|
||||||
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
|
}
|
||||||
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
compressionMethod,
|
compressionMethod,
|
||||||
enableCrossOsArchive
|
enableCrossOsArchive
|
||||||
});
|
});
|
||||||
const archiveLocation = `s3://${bucketName}/${s3Key}`;
|
const s3Key = `${s3Prefix}/${key}`;
|
||||||
const uploadProcess = (0, child_process_1.spawn)("aws", [
|
const multipartUpload = new lib_storage_1.Upload({
|
||||||
"s3",
|
client: s3Client,
|
||||||
"cp",
|
params: {
|
||||||
archivePath,
|
Bucket: bucketName,
|
||||||
archiveLocation
|
Key: s3Key,
|
||||||
]);
|
Body: (0, fs_1.createReadStream)(archivePath)
|
||||||
|
},
|
||||||
|
// Part size in bytes
|
||||||
|
partSize: 32 * 1024 * 1024,
|
||||||
|
// Max concurrency
|
||||||
|
queueSize: 14
|
||||||
|
});
|
||||||
// Commit Cache
|
// Commit Cache
|
||||||
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||||
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
||||||
const code = yield new Promise((resolve, reject) => {
|
core.info(`Uploading cache from ${archivePath} to ${bucketName}/${s3Key}`);
|
||||||
uploadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
multipartUpload.on("httpUploadProgress", progress => {
|
||||||
uploadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
core.info(`Uploaded ${progress.part}/${progress.total}.`);
|
||||||
uploadProcess.on("close", code => {
|
|
||||||
resolve(code);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
if (code === 0) {
|
yield multipartUpload.done();
|
||||||
core.info(`Cache saved successfully.`);
|
core.info(`Cache saved successfully.`);
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`File upload failed with code ${code}.`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
@ -93324,6 +94127,283 @@ function saveCache(paths, key, options, enableCrossOsArchive = false) {
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 6968:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.downloadCacheHttpClientConcurrent = exports.DownloadProgress = void 0;
|
||||||
|
// Just a copy of the original file from the toolkit/actions/cache repository, with a change for byte range used in the downloadCacheHttpClientConcurrent function.
|
||||||
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
|
const http_client_1 = __nccwpck_require__(6255);
|
||||||
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
|
const requestUtils_1 = __nccwpck_require__(3981);
|
||||||
|
/**
|
||||||
|
* Class for tracking the download state and displaying stats.
|
||||||
|
*/
|
||||||
|
class DownloadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.segmentIndex = 0;
|
||||||
|
this.segmentSize = 0;
|
||||||
|
this.segmentOffset = 0;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Progress to the next segment. Only call this method when the previous segment
|
||||||
|
* is complete.
|
||||||
|
*
|
||||||
|
* @param segmentSize the length of the next segment
|
||||||
|
*/
|
||||||
|
nextSegment(segmentSize) {
|
||||||
|
this.segmentOffset = this.segmentOffset + this.segmentSize;
|
||||||
|
this.segmentIndex = this.segmentIndex + 1;
|
||||||
|
this.segmentSize = segmentSize;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
core.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes received for the current segment.
|
||||||
|
*
|
||||||
|
* @param receivedBytes the number of bytes received
|
||||||
|
*/
|
||||||
|
setReceivedBytes(receivedBytes) {
|
||||||
|
this.receivedBytes = receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.segmentOffset + this.receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the download is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current download stats. Once the download completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.segmentOffset + this.receivedBytes;
|
||||||
|
const percentage = (100 *
|
||||||
|
(transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const downloadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setReceivedBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the download
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.DownloadProgress = DownloadProgress;
|
||||||
|
/**
|
||||||
|
* Download the cache using the Actions toolkit http-client concurrently
|
||||||
|
*
|
||||||
|
* @param archiveLocation the URL for the cache
|
||||||
|
* @param archivePath the local path where the cache is saved
|
||||||
|
*/
|
||||||
|
function downloadCacheHttpClientConcurrent(archiveLocation, archivePath, options) {
|
||||||
|
var _a;
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const archiveDescriptor = yield fs.promises.open(archivePath, "w");
|
||||||
|
const httpClient = new http_client_1.HttpClient("actions/cache", undefined, {
|
||||||
|
socketTimeout: options.timeoutInMs,
|
||||||
|
keepAlive: true
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const res = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCacheMetadata", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.request("GET", archiveLocation, null, {
|
||||||
|
Range: "bytes=0-1"
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
const contentRange = res.message.headers["content-range"];
|
||||||
|
if (!contentRange) {
|
||||||
|
throw new Error("Range request not supported by server");
|
||||||
|
}
|
||||||
|
const match = contentRange === null || contentRange === void 0 ? void 0 : contentRange.match(/bytes \d+-\d+\/(\d+)/);
|
||||||
|
if (!match) {
|
||||||
|
throw new Error("Content-Range header in server response not in correct format");
|
||||||
|
}
|
||||||
|
const length = parseInt(match[1]);
|
||||||
|
if (Number.isNaN(length)) {
|
||||||
|
throw new Error(`Could not interpret Content-Length: ${length}`);
|
||||||
|
}
|
||||||
|
const downloads = [];
|
||||||
|
const blockSize = 32 * 1024 * 1024;
|
||||||
|
for (let offset = 0; offset < length; offset += blockSize) {
|
||||||
|
const count = Math.min(blockSize, length - offset);
|
||||||
|
downloads.push({
|
||||||
|
offset,
|
||||||
|
promiseGetter: () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield downloadSegmentRetry(httpClient, archiveLocation, offset, count);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// reverse to use .pop instead of .shift
|
||||||
|
downloads.reverse();
|
||||||
|
let actives = 0;
|
||||||
|
let bytesDownloaded = 0;
|
||||||
|
const progress = new DownloadProgress(length);
|
||||||
|
progress.startDisplayTimer();
|
||||||
|
const progressFn = progress.onProgress();
|
||||||
|
const activeDownloads = [];
|
||||||
|
let nextDownload;
|
||||||
|
const waitAndWrite = () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const segment = yield Promise.race(Object.values(activeDownloads));
|
||||||
|
yield archiveDescriptor.write(segment.buffer, 0, segment.count, segment.offset);
|
||||||
|
actives--;
|
||||||
|
delete activeDownloads[segment.offset];
|
||||||
|
bytesDownloaded += segment.count;
|
||||||
|
progressFn({ loadedBytes: bytesDownloaded });
|
||||||
|
});
|
||||||
|
while ((nextDownload = downloads.pop())) {
|
||||||
|
activeDownloads[nextDownload.offset] = nextDownload.promiseGetter();
|
||||||
|
actives++;
|
||||||
|
if (actives >= ((_a = options.downloadConcurrency) !== null && _a !== void 0 ? _a : 10)) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (actives > 0) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
httpClient.dispose();
|
||||||
|
yield archiveDescriptor.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent;
|
||||||
|
function downloadSegmentRetry(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const retries = 5;
|
||||||
|
let failures = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const timeout = 30000;
|
||||||
|
const result = yield promiseWithTimeout(timeout, downloadSegment(httpClient, archiveLocation, offset, count));
|
||||||
|
if (typeof result === "string") {
|
||||||
|
throw new Error("downloadSegmentRetry failed due to timeout");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (failures >= retries) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function downloadSegment(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const partRes = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCachePart", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.get(archiveLocation, {
|
||||||
|
Range: `bytes=${offset}-${offset + count - 1}`
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
if (!partRes.readBodyBuffer) {
|
||||||
|
throw new Error("Expected HttpClientResponse to implement readBodyBuffer");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
offset,
|
||||||
|
count,
|
||||||
|
buffer: yield partRes.readBodyBuffer()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const promiseWithTimeout = (timeoutMs, promise) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
|
let timeoutHandle;
|
||||||
|
const timeoutPromise = new Promise(resolve => {
|
||||||
|
timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
|
||||||
|
});
|
||||||
|
return Promise.race([promise, timeoutPromise]).then(result => {
|
||||||
|
clearTimeout(timeoutHandle);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 6589:
|
/***/ 6589:
|
||||||
|
|
|
||||||
|
|
@ -25009,6 +25009,481 @@ const client_sts_1 = __nccwpck_require__(2209);
|
||||||
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
Object.defineProperty(exports, "getDefaultRoleAssumerWithWebIdentity", ({ enumerable: true, get: function () { return client_sts_1.getDefaultRoleAssumerWithWebIdentity; } }));
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3087:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
Upload: () => Upload
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var import_client_s3 = __nccwpck_require__(9250);
|
||||||
|
var import_abort_controller = __nccwpck_require__(7020);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_smithy_client = __nccwpck_require__(3570);
|
||||||
|
var import_events = __nccwpck_require__(2361);
|
||||||
|
|
||||||
|
// src/bytelength.ts
|
||||||
|
var import_runtimeConfig = __nccwpck_require__(3407);
|
||||||
|
var byteLength = /* @__PURE__ */ __name((input) => {
|
||||||
|
if (input === null || input === void 0)
|
||||||
|
return 0;
|
||||||
|
if (typeof input === "string")
|
||||||
|
input = Buffer.from(input);
|
||||||
|
if (typeof input.byteLength === "number") {
|
||||||
|
return input.byteLength;
|
||||||
|
} else if (typeof input.length === "number") {
|
||||||
|
return input.length;
|
||||||
|
} else if (typeof input.size === "number") {
|
||||||
|
return input.size;
|
||||||
|
} else if (typeof input.path === "string") {
|
||||||
|
try {
|
||||||
|
return import_runtimeConfig.ClientDefaultValues.lstatSync(input.path).size;
|
||||||
|
} catch (error) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return void 0;
|
||||||
|
}, "byteLength");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
|
||||||
|
var import_stream = __nccwpck_require__(2781);
|
||||||
|
|
||||||
|
// src/chunks/getChunkBuffer.ts
|
||||||
|
async function* getChunkBuffer(data, partSize) {
|
||||||
|
let partNumber = 1;
|
||||||
|
let startByte = 0;
|
||||||
|
let endByte = partSize;
|
||||||
|
while (endByte < data.byteLength) {
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte, endByte)
|
||||||
|
};
|
||||||
|
partNumber += 1;
|
||||||
|
startByte = endByte;
|
||||||
|
endByte = startByte + partSize;
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: data.slice(startByte),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkBuffer, "getChunkBuffer");
|
||||||
|
|
||||||
|
// src/chunks/getChunkStream.ts
|
||||||
|
var import_buffer = __nccwpck_require__(4300);
|
||||||
|
async function* getChunkStream(data, partSize, getNextData) {
|
||||||
|
let partNumber = 1;
|
||||||
|
const currentBuffer = { chunks: [], length: 0 };
|
||||||
|
for await (const datum of getNextData(data)) {
|
||||||
|
currentBuffer.chunks.push(datum);
|
||||||
|
currentBuffer.length += datum.length;
|
||||||
|
while (currentBuffer.length >= partSize) {
|
||||||
|
const dataChunk = currentBuffer.chunks.length > 1 ? import_buffer.Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0];
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: dataChunk.slice(0, partSize)
|
||||||
|
};
|
||||||
|
currentBuffer.chunks = [dataChunk.slice(partSize)];
|
||||||
|
currentBuffer.length = currentBuffer.chunks[0].length;
|
||||||
|
partNumber += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield {
|
||||||
|
partNumber,
|
||||||
|
data: import_buffer.Buffer.concat(currentBuffer.chunks),
|
||||||
|
lastPart: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
__name(getChunkStream, "getChunkStream");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadable.ts
|
||||||
|
|
||||||
|
async function* getDataReadable(data) {
|
||||||
|
for await (const chunk of data) {
|
||||||
|
yield import_buffer.Buffer.from(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadable, "getDataReadable");
|
||||||
|
|
||||||
|
// src/chunks/getDataReadableStream.ts
|
||||||
|
|
||||||
|
async function* getDataReadableStream(data) {
|
||||||
|
const reader = data.getReader();
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done)
|
||||||
|
return;
|
||||||
|
yield import_buffer.Buffer.from(value);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
reader.releaseLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__name(getDataReadableStream, "getDataReadableStream");
|
||||||
|
|
||||||
|
// src/chunker.ts
|
||||||
|
var getChunk = /* @__PURE__ */ __name((data, partSize) => {
|
||||||
|
if (data instanceof import_buffer.Buffer) {
|
||||||
|
return getChunkBuffer(data, partSize);
|
||||||
|
} else if (data instanceof import_stream.Readable) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadable);
|
||||||
|
} else if (data instanceof String || typeof data === "string" || data instanceof Uint8Array) {
|
||||||
|
return getChunkBuffer(import_buffer.Buffer.from(data), partSize);
|
||||||
|
}
|
||||||
|
if (typeof data.stream === "function") {
|
||||||
|
return getChunkStream(data.stream(), partSize, getDataReadableStream);
|
||||||
|
} else if (data instanceof ReadableStream) {
|
||||||
|
return getChunkStream(data, partSize, getDataReadableStream);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
"Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, "getChunk");
|
||||||
|
|
||||||
|
// src/Upload.ts
|
||||||
|
var MIN_PART_SIZE = 1024 * 1024 * 5;
|
||||||
|
var _Upload = class _Upload extends import_events.EventEmitter {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
/**
|
||||||
|
* S3 multipart upload does not allow more than 10000 parts.
|
||||||
|
*/
|
||||||
|
this.MAX_PARTS = 1e4;
|
||||||
|
// Defaults.
|
||||||
|
this.queueSize = 4;
|
||||||
|
this.partSize = MIN_PART_SIZE;
|
||||||
|
this.leavePartsOnError = false;
|
||||||
|
this.tags = [];
|
||||||
|
this.concurrentUploaders = [];
|
||||||
|
this.uploadedParts = [];
|
||||||
|
this.isMultiPart = true;
|
||||||
|
this.queueSize = options.queueSize || this.queueSize;
|
||||||
|
this.partSize = options.partSize || this.partSize;
|
||||||
|
this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
|
||||||
|
this.tags = options.tags || this.tags;
|
||||||
|
this.client = options.client;
|
||||||
|
this.params = options.params;
|
||||||
|
this.__validateInput();
|
||||||
|
this.totalBytes = byteLength(this.params.Body);
|
||||||
|
this.bytesUploadedSoFar = 0;
|
||||||
|
this.abortController = options.abortController ?? new import_abort_controller.AbortController();
|
||||||
|
}
|
||||||
|
async abort() {
|
||||||
|
this.abortController.abort();
|
||||||
|
}
|
||||||
|
async done() {
|
||||||
|
return await Promise.race([this.__doMultipartUpload(), this.__abortTimeout(this.abortController.signal)]);
|
||||||
|
}
|
||||||
|
on(event, listener) {
|
||||||
|
this.uploadEvent = event;
|
||||||
|
return super.on(event, listener);
|
||||||
|
}
|
||||||
|
async __uploadUsingPut(dataPart) {
|
||||||
|
var _a;
|
||||||
|
this.isMultiPart = false;
|
||||||
|
const params = { ...this.params, Body: dataPart.data };
|
||||||
|
const clientConfig = this.client.config;
|
||||||
|
const requestHandler = clientConfig.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event) => {
|
||||||
|
this.bytesUploadedSoFar = event.loaded;
|
||||||
|
this.totalBytes = event.total;
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const resolved = await Promise.all([this.client.send(new import_client_s3.PutObjectCommand(params)), (_a = clientConfig == null ? void 0 : clientConfig.endpoint) == null ? void 0 : _a.call(clientConfig)]);
|
||||||
|
const putResult = resolved[0];
|
||||||
|
let endpoint = resolved[1];
|
||||||
|
if (!endpoint) {
|
||||||
|
endpoint = (0, import_middleware_endpoint.toEndpointV1)(
|
||||||
|
await (0, import_middleware_endpoint.getEndpointFromInstructions)(params, import_client_s3.PutObjectCommand, {
|
||||||
|
...clientConfig
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!endpoint) {
|
||||||
|
throw new Error('Could not resolve endpoint from S3 "client.config.endpoint()" nor EndpointsV2.');
|
||||||
|
}
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const locationKey = this.params.Key.split("/").map((segment) => (0, import_smithy_client.extendedEncodeURIComponent)(segment)).join("/");
|
||||||
|
const locationBucket = (0, import_smithy_client.extendedEncodeURIComponent)(this.params.Bucket);
|
||||||
|
const Location = (() => {
|
||||||
|
const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`);
|
||||||
|
const forcePathStyle = this.client.config.forcePathStyle;
|
||||||
|
if (forcePathStyle) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationBucket}/${locationKey}`;
|
||||||
|
}
|
||||||
|
if (endpointHostnameIncludesBucket) {
|
||||||
|
return `${endpoint.protocol}//${endpoint.hostname}/${locationKey}`;
|
||||||
|
}
|
||||||
|
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}/${locationKey}`;
|
||||||
|
})();
|
||||||
|
this.singleUploadResult = {
|
||||||
|
...putResult,
|
||||||
|
Bucket: this.params.Bucket,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Location
|
||||||
|
};
|
||||||
|
const totalSize = byteLength(dataPart.data);
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: totalSize,
|
||||||
|
total: totalSize,
|
||||||
|
part: 1,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async __createMultipartUpload() {
|
||||||
|
if (!this.createMultiPartPromise) {
|
||||||
|
const createCommandParams = { ...this.params, Body: void 0 };
|
||||||
|
this.createMultiPartPromise = this.client.send(new import_client_s3.CreateMultipartUploadCommand(createCommandParams));
|
||||||
|
}
|
||||||
|
return this.createMultiPartPromise;
|
||||||
|
}
|
||||||
|
async __doConcurrentUpload(dataFeeder) {
|
||||||
|
for await (const dataPart of dataFeeder) {
|
||||||
|
if (this.uploadedParts.length > this.MAX_PARTS) {
|
||||||
|
throw new Error(
|
||||||
|
`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.params.Key} and ${this.params.Bucket}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dataPart.partNumber === 1 && dataPart.lastPart) {
|
||||||
|
return await this.__uploadUsingPut(dataPart);
|
||||||
|
}
|
||||||
|
if (!this.uploadId) {
|
||||||
|
const { UploadId } = await this.__createMultipartUpload();
|
||||||
|
this.uploadId = UploadId;
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const partSize = byteLength(dataPart.data) || 0;
|
||||||
|
const requestHandler = this.client.config.requestHandler;
|
||||||
|
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||||
|
let lastSeenBytes = 0;
|
||||||
|
const uploadEventListener = /* @__PURE__ */ __name((event, request) => {
|
||||||
|
const requestPartSize = Number(request.query["partNumber"]) || -1;
|
||||||
|
if (requestPartSize !== dataPart.partNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.total && partSize) {
|
||||||
|
this.bytesUploadedSoFar += event.loaded - lastSeenBytes;
|
||||||
|
lastSeenBytes = event.loaded;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
}, "uploadEventListener");
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
const partResult = await this.client.send(
|
||||||
|
new import_client_s3.UploadPartCommand({
|
||||||
|
...this.params,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
Body: dataPart.data,
|
||||||
|
PartNumber: dataPart.partNumber
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (eventEmitter !== null) {
|
||||||
|
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||||
|
}
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!partResult.ETag) {
|
||||||
|
throw new Error(
|
||||||
|
`Part ${dataPart.partNumber} is missing ETag in UploadPart response. Missing Bucket CORS configuration for ETag header?`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.uploadedParts.push({
|
||||||
|
PartNumber: dataPart.partNumber,
|
||||||
|
ETag: partResult.ETag,
|
||||||
|
...partResult.ChecksumCRC32 && { ChecksumCRC32: partResult.ChecksumCRC32 },
|
||||||
|
...partResult.ChecksumCRC32C && { ChecksumCRC32C: partResult.ChecksumCRC32C },
|
||||||
|
...partResult.ChecksumSHA1 && { ChecksumSHA1: partResult.ChecksumSHA1 },
|
||||||
|
...partResult.ChecksumSHA256 && { ChecksumSHA256: partResult.ChecksumSHA256 }
|
||||||
|
});
|
||||||
|
if (eventEmitter === null) {
|
||||||
|
this.bytesUploadedSoFar += partSize;
|
||||||
|
}
|
||||||
|
this.__notifyProgress({
|
||||||
|
loaded: this.bytesUploadedSoFar,
|
||||||
|
total: this.totalBytes,
|
||||||
|
part: dataPart.partNumber,
|
||||||
|
Key: this.params.Key,
|
||||||
|
Bucket: this.params.Bucket
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (!this.uploadId) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (this.leavePartsOnError) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __doMultipartUpload() {
|
||||||
|
const dataFeeder = getChunk(this.params.Body, this.partSize);
|
||||||
|
for (let index = 0; index < this.queueSize; index++) {
|
||||||
|
const currentUpload = this.__doConcurrentUpload(dataFeeder);
|
||||||
|
this.concurrentUploaders.push(currentUpload);
|
||||||
|
}
|
||||||
|
await Promise.all(this.concurrentUploaders);
|
||||||
|
if (this.abortController.signal.aborted) {
|
||||||
|
throw Object.assign(new Error("Upload aborted."), { name: "AbortError" });
|
||||||
|
}
|
||||||
|
let result;
|
||||||
|
if (this.isMultiPart) {
|
||||||
|
this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
|
||||||
|
const uploadCompleteParams = {
|
||||||
|
...this.params,
|
||||||
|
Body: void 0,
|
||||||
|
UploadId: this.uploadId,
|
||||||
|
MultipartUpload: {
|
||||||
|
Parts: this.uploadedParts
|
||||||
|
}
|
||||||
|
};
|
||||||
|
result = await this.client.send(new import_client_s3.CompleteMultipartUploadCommand(uploadCompleteParams));
|
||||||
|
if (typeof (result == null ? void 0 : result.Location) === "string" && result.Location.includes("%2F")) {
|
||||||
|
result.Location = result.Location.replace(/%2F/g, "/");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = this.singleUploadResult;
|
||||||
|
}
|
||||||
|
if (this.tags.length) {
|
||||||
|
await this.client.send(
|
||||||
|
new import_client_s3.PutObjectTaggingCommand({
|
||||||
|
...this.params,
|
||||||
|
Tagging: {
|
||||||
|
TagSet: this.tags
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
__notifyProgress(progress) {
|
||||||
|
if (this.uploadEvent) {
|
||||||
|
this.emit(this.uploadEvent, progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __abortTimeout(abortSignal) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
abortSignal.onabort = () => {
|
||||||
|
const abortError = new Error("Upload aborted.");
|
||||||
|
abortError.name = "AbortError";
|
||||||
|
reject(abortError);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
__validateInput() {
|
||||||
|
if (!this.params) {
|
||||||
|
throw new Error(`InputError: Upload requires params to be passed to upload.`);
|
||||||
|
}
|
||||||
|
if (!this.client) {
|
||||||
|
throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
|
||||||
|
}
|
||||||
|
if (this.partSize < MIN_PART_SIZE) {
|
||||||
|
throw new Error(
|
||||||
|
`EntityTooSmall: Your proposed upload partsize [${this.partSize}] is smaller than the minimum allowed size [${MIN_PART_SIZE}] (5MB)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.queueSize < 1) {
|
||||||
|
throw new Error(`Queue size: Must have at least one uploading queue.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_Upload, "Upload");
|
||||||
|
var Upload = _Upload;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 3407:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientDefaultValues = void 0;
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
|
const runtimeConfig_shared_1 = __nccwpck_require__(9583);
|
||||||
|
exports.ClientDefaultValues = {
|
||||||
|
...runtimeConfig_shared_1.ClientSharedValues,
|
||||||
|
runtime: "node",
|
||||||
|
lstatSync: fs_1.lstatSync,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 9583:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.ClientSharedValues = void 0;
|
||||||
|
exports.ClientSharedValues = {
|
||||||
|
lstatSync: () => { },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 6689:
|
/***/ 6689:
|
||||||
|
|
@ -27260,6 +27735,176 @@ var resolveRegionConfig = /* @__PURE__ */ __name((input) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5052:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
S3RequestPresigner: () => S3RequestPresigner,
|
||||||
|
getSignedUrl: () => getSignedUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var import_util_format_url = __nccwpck_require__(7053);
|
||||||
|
var import_middleware_endpoint = __nccwpck_require__(2918);
|
||||||
|
var import_protocol_http = __nccwpck_require__(9556);
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var import_signature_v4_multi_region = __nccwpck_require__(1856);
|
||||||
|
|
||||||
|
// src/constants.ts
|
||||||
|
var UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
|
||||||
|
var SHA256_HEADER = "X-Amz-Content-Sha256";
|
||||||
|
|
||||||
|
// src/presigner.ts
|
||||||
|
var _S3RequestPresigner = class _S3RequestPresigner {
|
||||||
|
constructor(options) {
|
||||||
|
const resolvedOptions = {
|
||||||
|
// Allow `signingName` because we want to support usecase of supply client's resolved config
|
||||||
|
// directly. Where service equals signingName.
|
||||||
|
service: options.signingName || options.service || "s3",
|
||||||
|
uriEscapePath: options.uriEscapePath || false,
|
||||||
|
applyChecksum: options.applyChecksum || false,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
this.signer = new import_signature_v4_multi_region.SignatureV4MultiRegion(resolvedOptions);
|
||||||
|
}
|
||||||
|
presign(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presign(requestToSign, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
presignWithCredentials(requestToSign, credentials, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set(), ...options } = {}) {
|
||||||
|
this.prepareRequest(requestToSign, {
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders
|
||||||
|
});
|
||||||
|
return this.signer.presignWithCredentials(requestToSign, credentials, {
|
||||||
|
expiresIn: 900,
|
||||||
|
unsignableHeaders,
|
||||||
|
unhoistableHeaders,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
prepareRequest(requestToSign, { unsignableHeaders = /* @__PURE__ */ new Set(), unhoistableHeaders = /* @__PURE__ */ new Set() } = {}) {
|
||||||
|
unsignableHeaders.add("content-type");
|
||||||
|
Object.keys(requestToSign.headers).map((header) => header.toLowerCase()).filter((header) => header.startsWith("x-amz-server-side-encryption")).forEach((header) => {
|
||||||
|
unhoistableHeaders.add(header);
|
||||||
|
});
|
||||||
|
requestToSign.headers[SHA256_HEADER] = UNSIGNED_PAYLOAD;
|
||||||
|
const currentHostHeader = requestToSign.headers.host;
|
||||||
|
const port = requestToSign.port;
|
||||||
|
const expectedHostHeader = `${requestToSign.hostname}${requestToSign.port != null ? ":" + port : ""}`;
|
||||||
|
if (!currentHostHeader || currentHostHeader === requestToSign.hostname && requestToSign.port != null) {
|
||||||
|
requestToSign.headers.host = expectedHostHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_S3RequestPresigner, "S3RequestPresigner");
|
||||||
|
var S3RequestPresigner = _S3RequestPresigner;
|
||||||
|
|
||||||
|
// src/getSignedUrl.ts
|
||||||
|
var getSignedUrl = /* @__PURE__ */ __name(async (client, command, options = {}) => {
|
||||||
|
var _a, _b, _c;
|
||||||
|
let s3Presigner;
|
||||||
|
let region;
|
||||||
|
if (typeof client.config.endpointProvider === "function") {
|
||||||
|
const endpointV2 = await (0, import_middleware_endpoint.getEndpointFromInstructions)(
|
||||||
|
command.input,
|
||||||
|
command.constructor,
|
||||||
|
client.config
|
||||||
|
);
|
||||||
|
const authScheme = (_b = (_a = endpointV2.properties) == null ? void 0 : _a.authSchemes) == null ? void 0 : _b[0];
|
||||||
|
if ((authScheme == null ? void 0 : authScheme.name) === "sigv4a") {
|
||||||
|
region = (_c = authScheme == null ? void 0 : authScheme.signingRegionSet) == null ? void 0 : _c.join(",");
|
||||||
|
} else {
|
||||||
|
region = authScheme == null ? void 0 : authScheme.signingRegion;
|
||||||
|
}
|
||||||
|
s3Presigner = new S3RequestPresigner({
|
||||||
|
...client.config,
|
||||||
|
signingName: authScheme == null ? void 0 : authScheme.signingName,
|
||||||
|
region: async () => region
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
s3Presigner = new S3RequestPresigner(client.config);
|
||||||
|
}
|
||||||
|
const presignInterceptMiddleware = /* @__PURE__ */ __name((next, context) => async (args) => {
|
||||||
|
const { request } = args;
|
||||||
|
if (!import_protocol_http.HttpRequest.isInstance(request)) {
|
||||||
|
throw new Error("Request to be presigned is not an valid HTTP request.");
|
||||||
|
}
|
||||||
|
delete request.headers["amz-sdk-invocation-id"];
|
||||||
|
delete request.headers["amz-sdk-request"];
|
||||||
|
delete request.headers["x-amz-user-agent"];
|
||||||
|
let presigned2;
|
||||||
|
const presignerOptions = {
|
||||||
|
...options,
|
||||||
|
signingRegion: options.signingRegion ?? context["signing_region"] ?? region,
|
||||||
|
signingService: options.signingService ?? context["signing_service"]
|
||||||
|
};
|
||||||
|
if (context.s3ExpressIdentity) {
|
||||||
|
presigned2 = await s3Presigner.presignWithCredentials(request, context.s3ExpressIdentity, presignerOptions);
|
||||||
|
} else {
|
||||||
|
presigned2 = await s3Presigner.presign(request, presignerOptions);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
// Intercept the middleware stack by returning fake response
|
||||||
|
response: {},
|
||||||
|
output: {
|
||||||
|
$metadata: { httpStatusCode: 200 },
|
||||||
|
presigned: presigned2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, "presignInterceptMiddleware");
|
||||||
|
const middlewareName = "presignInterceptMiddleware";
|
||||||
|
const clientStack = client.middlewareStack.clone();
|
||||||
|
clientStack.addRelativeTo(presignInterceptMiddleware, {
|
||||||
|
name: middlewareName,
|
||||||
|
relation: "before",
|
||||||
|
toMiddleware: "awsAuthMiddleware",
|
||||||
|
override: true
|
||||||
|
});
|
||||||
|
const handler = command.resolveMiddleware(clientStack, client.config, {});
|
||||||
|
const { output } = await handler({ input: command.input });
|
||||||
|
const { presigned } = output;
|
||||||
|
return (0, import_util_format_url.formatUrl)(presigned);
|
||||||
|
}, "getSignedUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 1856:
|
/***/ 1856:
|
||||||
|
|
@ -28054,6 +28699,72 @@ import_util_endpoints.customEndpointFunctions.aws = awsEndpointFunctions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7053:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
formatUrl: () => formatUrl
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
var import_querystring_builder = __nccwpck_require__(8031);
|
||||||
|
function formatUrl(request) {
|
||||||
|
const { port, query } = request;
|
||||||
|
let { protocol, path, hostname } = request;
|
||||||
|
if (protocol && protocol.slice(-1) !== ":") {
|
||||||
|
protocol += ":";
|
||||||
|
}
|
||||||
|
if (port) {
|
||||||
|
hostname += `:${port}`;
|
||||||
|
}
|
||||||
|
if (path && path.charAt(0) !== "/") {
|
||||||
|
path = `/${path}`;
|
||||||
|
}
|
||||||
|
let queryString = query ? (0, import_querystring_builder.buildQueryString)(query) : "";
|
||||||
|
if (queryString && queryString[0] !== "?") {
|
||||||
|
queryString = `?${queryString}`;
|
||||||
|
}
|
||||||
|
let auth = "";
|
||||||
|
if (request.username != null || request.password != null) {
|
||||||
|
const username = request.username ?? "";
|
||||||
|
const password = request.password ?? "";
|
||||||
|
auth = `${username}:${password}@`;
|
||||||
|
}
|
||||||
|
let fragment = "";
|
||||||
|
if (request.fragment) {
|
||||||
|
fragment = `#${request.fragment}`;
|
||||||
|
}
|
||||||
|
return `${protocol}//${auth}${hostname}${path}${queryString}${fragment}`;
|
||||||
|
}
|
||||||
|
__name(formatUrl, "formatUrl");
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 8095:
|
/***/ 8095:
|
||||||
|
|
@ -66451,6 +67162,92 @@ exports.VERSION = void 0;
|
||||||
exports.VERSION = '1.4.0';
|
exports.VERSION = '1.4.0';
|
||||||
//# sourceMappingURL=version.js.map
|
//# sourceMappingURL=version.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 7020:
|
||||||
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
AbortController: () => AbortController,
|
||||||
|
AbortHandler: () => import_types.AbortHandler,
|
||||||
|
AbortSignal: () => AbortSignal,
|
||||||
|
IAbortController: () => import_types.AbortController,
|
||||||
|
IAbortSignal: () => import_types.AbortSignal
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
|
||||||
|
|
||||||
|
// src/AbortSignal.ts
|
||||||
|
var import_types = __nccwpck_require__(5756);
|
||||||
|
var _AbortSignal = class _AbortSignal {
|
||||||
|
constructor() {
|
||||||
|
this.onabort = null;
|
||||||
|
this._aborted = false;
|
||||||
|
Object.defineProperty(this, "_aborted", {
|
||||||
|
value: false,
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether the associated operation has already been cancelled.
|
||||||
|
*/
|
||||||
|
get aborted() {
|
||||||
|
return this._aborted;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
abort() {
|
||||||
|
this._aborted = true;
|
||||||
|
if (this.onabort) {
|
||||||
|
this.onabort(this);
|
||||||
|
this.onabort = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortSignal, "AbortSignal");
|
||||||
|
var AbortSignal = _AbortSignal;
|
||||||
|
|
||||||
|
// src/AbortController.ts
|
||||||
|
var _AbortController = class _AbortController {
|
||||||
|
constructor() {
|
||||||
|
this.signal = new AbortSignal();
|
||||||
|
}
|
||||||
|
abort() {
|
||||||
|
this.signal.abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__name(_AbortController, "AbortController");
|
||||||
|
var AbortController = _AbortController;
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
|
||||||
|
0 && (0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 3098:
|
/***/ 3098:
|
||||||
|
|
@ -92969,12 +93766,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
exports.saveCache = exports.downloadCache = exports.getCacheEntry = exports.getCacheVersion = void 0;
|
||||||
const client_s3_1 = __nccwpck_require__(9250);
|
const client_s3_1 = __nccwpck_require__(9250);
|
||||||
const child_process_1 = __nccwpck_require__(2081);
|
const { getSignedUrl } = __nccwpck_require__(5052);
|
||||||
|
const fs_1 = __nccwpck_require__(7147);
|
||||||
const crypto = __importStar(__nccwpck_require__(6113));
|
const crypto = __importStar(__nccwpck_require__(6113));
|
||||||
|
const options_1 = __nccwpck_require__(6215);
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const utils = __importStar(__nccwpck_require__(1518));
|
const utils = __importStar(__nccwpck_require__(1518));
|
||||||
|
const lib_storage_1 = __nccwpck_require__(3087);
|
||||||
|
const downloadUtils_1 = __nccwpck_require__(6968);
|
||||||
const versionSalt = "1.0";
|
const versionSalt = "1.0";
|
||||||
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
const bucketName = process.env.RUNS_ON_S3_BUCKET_CACHE;
|
||||||
|
const region = process.env.RUNS_ON_AWS_REGION ||
|
||||||
|
process.env.AWS_REGION ||
|
||||||
|
process.env.AWS_DEFAULT_REGION;
|
||||||
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false) {
|
||||||
// don't pass changes upstream
|
// don't pass changes upstream
|
||||||
const components = paths.slice();
|
const components = paths.slice();
|
||||||
|
|
@ -92995,31 +93799,33 @@ function getCacheVersion(paths, compressionMethod, enableCrossOsArchive = false)
|
||||||
.digest("hex");
|
.digest("hex");
|
||||||
}
|
}
|
||||||
exports.getCacheVersion = getCacheVersion;
|
exports.getCacheVersion = getCacheVersion;
|
||||||
function getCacheEntryS3Key(restoreKey, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getS3Prefix(paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
const repository = process.env.GITHUB_REPOSITORY;
|
const repository = process.env.GITHUB_REPOSITORY;
|
||||||
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
const version = getCacheVersion(paths, compressionMethod, enableCrossOsArchive);
|
||||||
return ["cache", repository, version, restoreKey].join("/");
|
return ["cache", repository, version].join("/");
|
||||||
}
|
}
|
||||||
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive }) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const cacheEntry = {};
|
const cacheEntry = {};
|
||||||
const s3Client = new client_s3_1.S3Client();
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
// Find the most recent key matching one of the restoreKeys prefixes
|
// Find the most recent key matching one of the restoreKeys prefixes
|
||||||
for (const restoreKey of keys) {
|
for (const restoreKey of keys) {
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
|
compressionMethod,
|
||||||
|
enableCrossOsArchive
|
||||||
|
});
|
||||||
const listObjectsParams = {
|
const listObjectsParams = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Prefix: getCacheEntryS3Key(restoreKey, paths, {
|
Prefix: [s3Prefix, restoreKey].join("/")
|
||||||
compressionMethod,
|
|
||||||
enableCrossOsArchive
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
const { Contents = [] } = yield s3Client.send(new client_s3_1.ListObjectsV2Command(listObjectsParams));
|
||||||
if (Contents.length > 0) {
|
if (Contents.length > 0) {
|
||||||
// Sort keys by LastModified time in descending order
|
// Sort keys by LastModified time in descending order
|
||||||
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
const sortedKeys = Contents.sort((a, b) => Number(b.LastModified) - Number(a.LastModified));
|
||||||
cacheEntry.cacheKey = sortedKeys[0].Key; // Return the most recent key
|
const s3Path = sortedKeys[0].Key; // Return the most recent key
|
||||||
cacheEntry.archiveLocation = `s3://${bucketName}/${cacheEntry.cacheKey}`;
|
cacheEntry.cacheKey = s3Path === null || s3Path === void 0 ? void 0 : s3Path.replace(`${s3Prefix}/`, "");
|
||||||
|
cacheEntry.archiveLocation = `s3://${bucketName}/${s3Path}`;
|
||||||
return cacheEntry;
|
return cacheEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93027,7 +93833,6 @@ function getCacheEntry(keys, paths, { compressionMethod, enableCrossOsArchive })
|
||||||
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
console.error(`Error listing objects with prefix ${restoreKey} in bucket ${bucketName}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`No matching keys found in bucket ${bucketName}`);
|
|
||||||
return cacheEntry; // No keys found
|
return cacheEntry; // No keys found
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -93037,26 +93842,21 @@ function downloadCache(archiveLocation, archivePath, options) {
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const downloadProcess = (0, child_process_1.spawn)("aws", [
|
if (!region) {
|
||||||
"s3",
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
"cp",
|
}
|
||||||
archiveLocation,
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
archivePath
|
const archiveUrl = new URL(archiveLocation);
|
||||||
]);
|
const objectKey = archiveUrl.pathname.slice(1);
|
||||||
return new Promise((resolve, reject) => {
|
const command = new client_s3_1.GetObjectCommand({
|
||||||
downloadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
Bucket: bucketName,
|
||||||
downloadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
Key: objectKey
|
||||||
downloadProcess.on("close", code => {
|
|
||||||
if (code === 0) {
|
|
||||||
console.log(`File downloaded successfully from ${archiveLocation} to ${archivePath}`);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(`File download failed with code ${code}`);
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
const url = yield getSignedUrl(s3Client, command, {
|
||||||
|
expiresIn: 3600
|
||||||
|
});
|
||||||
|
const downloadOptions = (0, options_1.getDownloadOptions)(Object.assign(Object.assign({}, options), { downloadConcurrency: 14, concurrentBlobDownloads: true }));
|
||||||
|
yield (0, downloadUtils_1.downloadCacheHttpClientConcurrent)(url, archivePath, downloadOptions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.downloadCache = downloadCache;
|
exports.downloadCache = downloadCache;
|
||||||
|
|
@ -93065,33 +93865,36 @@ function saveCache(key, paths, archivePath, { compressionMethod, enableCrossOsAr
|
||||||
if (!bucketName) {
|
if (!bucketName) {
|
||||||
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
throw new Error("Environment variable RUNS_ON_S3_BUCKET_CACHE not set");
|
||||||
}
|
}
|
||||||
const s3Key = getCacheEntryS3Key(key, paths, {
|
if (!region) {
|
||||||
|
throw new Error("Environment variable RUNS_ON_AWS_REGION not set");
|
||||||
|
}
|
||||||
|
const s3Client = new client_s3_1.S3Client({ region });
|
||||||
|
const s3Prefix = getS3Prefix(paths, {
|
||||||
compressionMethod,
|
compressionMethod,
|
||||||
enableCrossOsArchive
|
enableCrossOsArchive
|
||||||
});
|
});
|
||||||
const archiveLocation = `s3://${bucketName}/${s3Key}`;
|
const s3Key = `${s3Prefix}/${key}`;
|
||||||
const uploadProcess = (0, child_process_1.spawn)("aws", [
|
const multipartUpload = new lib_storage_1.Upload({
|
||||||
"s3",
|
client: s3Client,
|
||||||
"cp",
|
params: {
|
||||||
archivePath,
|
Bucket: bucketName,
|
||||||
archiveLocation
|
Key: s3Key,
|
||||||
]);
|
Body: (0, fs_1.createReadStream)(archivePath)
|
||||||
|
},
|
||||||
|
// Part size in bytes
|
||||||
|
partSize: 32 * 1024 * 1024,
|
||||||
|
// Max concurrency
|
||||||
|
queueSize: 14
|
||||||
|
});
|
||||||
// Commit Cache
|
// Commit Cache
|
||||||
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
const cacheSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||||
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
core.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`);
|
||||||
const code = yield new Promise((resolve, reject) => {
|
core.info(`Uploading cache from ${archivePath} to ${bucketName}/${s3Key}`);
|
||||||
uploadProcess.stdout.on("data", data => console.log(`stdout: ${data}`));
|
multipartUpload.on("httpUploadProgress", progress => {
|
||||||
uploadProcess.stderr.on("data", data => console.error(`stderr: ${data}`));
|
core.info(`Uploaded ${progress.part}/${progress.total}.`);
|
||||||
uploadProcess.on("close", code => {
|
|
||||||
resolve(code);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
if (code === 0) {
|
yield multipartUpload.done();
|
||||||
core.info(`Cache saved successfully.`);
|
core.info(`Cache saved successfully.`);
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`File upload failed with code ${code}.`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
@ -93324,6 +94127,283 @@ function saveCache(paths, key, options, enableCrossOsArchive = false) {
|
||||||
exports.saveCache = saveCache;
|
exports.saveCache = saveCache;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 6968:
|
||||||
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.downloadCacheHttpClientConcurrent = exports.DownloadProgress = void 0;
|
||||||
|
// Just a copy of the original file from the toolkit/actions/cache repository, with a change for byte range used in the downloadCacheHttpClientConcurrent function.
|
||||||
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
|
const http_client_1 = __nccwpck_require__(6255);
|
||||||
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
|
const requestUtils_1 = __nccwpck_require__(3981);
|
||||||
|
/**
|
||||||
|
* Class for tracking the download state and displaying stats.
|
||||||
|
*/
|
||||||
|
class DownloadProgress {
|
||||||
|
constructor(contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.segmentIndex = 0;
|
||||||
|
this.segmentSize = 0;
|
||||||
|
this.segmentOffset = 0;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
this.displayedComplete = false;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Progress to the next segment. Only call this method when the previous segment
|
||||||
|
* is complete.
|
||||||
|
*
|
||||||
|
* @param segmentSize the length of the next segment
|
||||||
|
*/
|
||||||
|
nextSegment(segmentSize) {
|
||||||
|
this.segmentOffset = this.segmentOffset + this.segmentSize;
|
||||||
|
this.segmentIndex = this.segmentIndex + 1;
|
||||||
|
this.segmentSize = segmentSize;
|
||||||
|
this.receivedBytes = 0;
|
||||||
|
core.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of bytes received for the current segment.
|
||||||
|
*
|
||||||
|
* @param receivedBytes the number of bytes received
|
||||||
|
*/
|
||||||
|
setReceivedBytes(receivedBytes) {
|
||||||
|
this.receivedBytes = receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the total number of bytes transferred.
|
||||||
|
*/
|
||||||
|
getTransferredBytes() {
|
||||||
|
return this.segmentOffset + this.receivedBytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns true if the download is complete.
|
||||||
|
*/
|
||||||
|
isDone() {
|
||||||
|
return this.getTransferredBytes() === this.contentLength;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prints the current download stats. Once the download completes, this will print one
|
||||||
|
* last line and then stop.
|
||||||
|
*/
|
||||||
|
display() {
|
||||||
|
if (this.displayedComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const transferredBytes = this.segmentOffset + this.receivedBytes;
|
||||||
|
const percentage = (100 *
|
||||||
|
(transferredBytes / this.contentLength)).toFixed(1);
|
||||||
|
const elapsedTime = Date.now() - this.startTime;
|
||||||
|
const downloadSpeed = (transferredBytes /
|
||||||
|
(1024 * 1024) /
|
||||||
|
(elapsedTime / 1000)).toFixed(1);
|
||||||
|
core.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`);
|
||||||
|
if (this.isDone()) {
|
||||||
|
this.displayedComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a function used to handle TransferProgressEvents.
|
||||||
|
*/
|
||||||
|
onProgress() {
|
||||||
|
return (progress) => {
|
||||||
|
this.setReceivedBytes(progress.loadedBytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the timer that displays the stats.
|
||||||
|
*
|
||||||
|
* @param delayInMs the delay between each write
|
||||||
|
*/
|
||||||
|
startDisplayTimer(delayInMs = 1000) {
|
||||||
|
const displayCallback = () => {
|
||||||
|
this.display();
|
||||||
|
if (!this.isDone()) {
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stops the timer that displays the stats. As this typically indicates the download
|
||||||
|
* is complete, this will display one last line, unless the last line has already
|
||||||
|
* been written.
|
||||||
|
*/
|
||||||
|
stopDisplayTimer() {
|
||||||
|
if (this.timeoutHandle) {
|
||||||
|
clearTimeout(this.timeoutHandle);
|
||||||
|
this.timeoutHandle = undefined;
|
||||||
|
}
|
||||||
|
this.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.DownloadProgress = DownloadProgress;
|
||||||
|
/**
|
||||||
|
* Download the cache using the Actions toolkit http-client concurrently
|
||||||
|
*
|
||||||
|
* @param archiveLocation the URL for the cache
|
||||||
|
* @param archivePath the local path where the cache is saved
|
||||||
|
*/
|
||||||
|
function downloadCacheHttpClientConcurrent(archiveLocation, archivePath, options) {
|
||||||
|
var _a;
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const archiveDescriptor = yield fs.promises.open(archivePath, "w");
|
||||||
|
const httpClient = new http_client_1.HttpClient("actions/cache", undefined, {
|
||||||
|
socketTimeout: options.timeoutInMs,
|
||||||
|
keepAlive: true
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const res = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCacheMetadata", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.request("GET", archiveLocation, null, {
|
||||||
|
Range: "bytes=0-1"
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
const contentRange = res.message.headers["content-range"];
|
||||||
|
if (!contentRange) {
|
||||||
|
throw new Error("Range request not supported by server");
|
||||||
|
}
|
||||||
|
const match = contentRange === null || contentRange === void 0 ? void 0 : contentRange.match(/bytes \d+-\d+\/(\d+)/);
|
||||||
|
if (!match) {
|
||||||
|
throw new Error("Content-Range header in server response not in correct format");
|
||||||
|
}
|
||||||
|
const length = parseInt(match[1]);
|
||||||
|
if (Number.isNaN(length)) {
|
||||||
|
throw new Error(`Could not interpret Content-Length: ${length}`);
|
||||||
|
}
|
||||||
|
const downloads = [];
|
||||||
|
const blockSize = 32 * 1024 * 1024;
|
||||||
|
for (let offset = 0; offset < length; offset += blockSize) {
|
||||||
|
const count = Math.min(blockSize, length - offset);
|
||||||
|
downloads.push({
|
||||||
|
offset,
|
||||||
|
promiseGetter: () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield downloadSegmentRetry(httpClient, archiveLocation, offset, count);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// reverse to use .pop instead of .shift
|
||||||
|
downloads.reverse();
|
||||||
|
let actives = 0;
|
||||||
|
let bytesDownloaded = 0;
|
||||||
|
const progress = new DownloadProgress(length);
|
||||||
|
progress.startDisplayTimer();
|
||||||
|
const progressFn = progress.onProgress();
|
||||||
|
const activeDownloads = [];
|
||||||
|
let nextDownload;
|
||||||
|
const waitAndWrite = () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const segment = yield Promise.race(Object.values(activeDownloads));
|
||||||
|
yield archiveDescriptor.write(segment.buffer, 0, segment.count, segment.offset);
|
||||||
|
actives--;
|
||||||
|
delete activeDownloads[segment.offset];
|
||||||
|
bytesDownloaded += segment.count;
|
||||||
|
progressFn({ loadedBytes: bytesDownloaded });
|
||||||
|
});
|
||||||
|
while ((nextDownload = downloads.pop())) {
|
||||||
|
activeDownloads[nextDownload.offset] = nextDownload.promiseGetter();
|
||||||
|
actives++;
|
||||||
|
if (actives >= ((_a = options.downloadConcurrency) !== null && _a !== void 0 ? _a : 10)) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (actives > 0) {
|
||||||
|
yield waitAndWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
httpClient.dispose();
|
||||||
|
yield archiveDescriptor.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent;
|
||||||
|
function downloadSegmentRetry(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const retries = 5;
|
||||||
|
let failures = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const timeout = 30000;
|
||||||
|
const result = yield promiseWithTimeout(timeout, downloadSegment(httpClient, archiveLocation, offset, count));
|
||||||
|
if (typeof result === "string") {
|
||||||
|
throw new Error("downloadSegmentRetry failed due to timeout");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (failures >= retries) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function downloadSegment(httpClient, archiveLocation, offset, count) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const partRes = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCachePart", () => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield httpClient.get(archiveLocation, {
|
||||||
|
Range: `bytes=${offset}-${offset + count - 1}`
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
if (!partRes.readBodyBuffer) {
|
||||||
|
throw new Error("Expected HttpClientResponse to implement readBodyBuffer");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
offset,
|
||||||
|
count,
|
||||||
|
buffer: yield partRes.readBodyBuffer()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const promiseWithTimeout = (timeoutMs, promise) => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
|
let timeoutHandle;
|
||||||
|
const timeoutPromise = new Promise(resolve => {
|
||||||
|
timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
|
||||||
|
});
|
||||||
|
return Promise.race([promise, timeoutPromise]).then(result => {
|
||||||
|
clearTimeout(timeoutHandle);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 6589:
|
/***/ 6589:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue