import { AwsClient } from "aws4fetch";
//#region src/presign-s3compat.ts
var InvalidPresignKeyError = class extends Error {
	name = "InvalidPresignKeyError";
	constructor(key) {
		super(`Presign key must be one exact object key, not a prefix or wildcard: ${key}`);
	}
};
function assertExactKey(key) {
	if (!key || key.includes("*") || key.includes("?") || key.endsWith("/")) throw new InvalidPresignKeyError(key);
}
function joinEndpoint(endpoint, key) {
	return `${endpoint.endsWith("/") ? endpoint.slice(0, -1) : endpoint}/${key.split("/").map((segment) => encodeURIComponent(segment)).join("/")}`;
}
/**
* Mint a browser-direct PUT URL for one exact R2 object key.
*
* Authz floor: single exact key (never prefix/wildcard), PUT-only, required bounded
* `expiresIn`, Content-Type bound in `X-Amz-SignedHeaders`.
*
* **Direct-PUT bypass contract (two control points):**
* - **Pre-issue:** host MUST call `checkStorageQuota` before minting — bytes hit R2 on PUT.
* - **Post-upload:** host MUST HEAD+range-GET first bytes → `detectMimeFromMagicBytes` + size,
*   or use proxy/direct-POST where the worker sees bytes. Content-Type binding pins the declared
*   type only — NOT spoof-protection.
*/
async function presignR2Put(creds, key, contentType, expiresIn) {
	assertExactKey(key);
	if (!Number.isFinite(expiresIn) || expiresIn <= 0) throw new RangeError("expiresIn must be a positive finite number of seconds");
	const client = new AwsClient({
		accessKeyId: creds.accessKeyId,
		secretAccessKey: creds.secretAccessKey,
		region: creds.region ?? "auto",
		service: "s3"
	});
	const objectUrl = `${joinEndpoint(creds.endpoint, key)}?X-Amz-Expires=${expiresIn}`;
	const signed = await client.sign(new Request(objectUrl, {
		method: "PUT",
		headers: { "Content-Type": contentType }
	}), { aws: {
		signQuery: true,
		allHeaders: true
	} });
	const headers = {};
	signed.headers.forEach((value, name) => {
		headers[name.toLowerCase()] = value;
	});
	return {
		url: signed.url,
		method: "PUT",
		headers
	};
}
//#endregion
export { InvalidPresignKeyError, presignR2Put };
