import { a as hashApiToken, r as generatePrefixedToken } from "./api-tokens-DsvvCtdh.mjs";
import { ulid } from "ulidx";

//#region src/api/handlers/api-tokens.ts
/**
* Create a new API token for a user.
*/
async function handleApiTokenCreate(db, userId, input) {
	try {
		const id = ulid();
		const { raw, hash, prefix } = generatePrefixedToken("ec_pat_");
		await db.insertInto("_emdash_api_tokens").values({
			id,
			name: input.name,
			token_hash: hash,
			prefix,
			user_id: userId,
			scopes: JSON.stringify(input.scopes),
			expires_at: input.expiresAt ?? null
		}).execute();
		return {
			success: true,
			data: {
				token: raw,
				info: {
					id,
					name: input.name,
					prefix,
					scopes: input.scopes,
					userId,
					expiresAt: input.expiresAt ?? null,
					lastUsedAt: null,
					createdAt: (/* @__PURE__ */ new Date()).toISOString()
				}
			}
		};
	} catch {
		return {
			success: false,
			error: {
				code: "TOKEN_CREATE_ERROR",
				message: "Failed to create API token"
			}
		};
	}
}
/**
* List all API tokens for a user (never returns the raw token or hash).
*/
async function handleApiTokenList(db, userId) {
	try {
		return {
			success: true,
			data: { items: (await db.selectFrom("_emdash_api_tokens").select([
				"id",
				"name",
				"prefix",
				"scopes",
				"user_id",
				"expires_at",
				"last_used_at",
				"created_at"
			]).where("user_id", "=", userId).orderBy("created_at", "desc").execute()).map((row) => ({
				id: row.id,
				name: row.name,
				prefix: row.prefix,
				scopes: JSON.parse(row.scopes),
				userId: row.user_id,
				expiresAt: row.expires_at,
				lastUsedAt: row.last_used_at,
				createdAt: row.created_at
			})) }
		};
	} catch {
		return {
			success: false,
			error: {
				code: "TOKEN_LIST_ERROR",
				message: "Failed to list API tokens"
			}
		};
	}
}
/**
* Revoke (delete) an API token.
*/
async function handleApiTokenRevoke(db, tokenId, userId) {
	try {
		if ((await db.deleteFrom("_emdash_api_tokens").where("id", "=", tokenId).where("user_id", "=", userId).executeTakeFirst()).numDeletedRows === 0n) return {
			success: false,
			error: {
				code: "NOT_FOUND",
				message: "Token not found"
			}
		};
		return {
			success: true,
			data: { revoked: true }
		};
	} catch {
		return {
			success: false,
			error: {
				code: "TOKEN_REVOKE_ERROR",
				message: "Failed to revoke API token"
			}
		};
	}
}
/**
* Delete every token with the given name for a user, returning how many were
* removed. Token names aren't unique, so this is a bulk delete — used by the
* dev-bypass flow to keep a single `dev-bypass-token` instead of minting a new
* one on every reset.
*/
async function deleteApiTokensByName(db, userId, name) {
	const result = await db.deleteFrom("_emdash_api_tokens").where("user_id", "=", userId).where("name", "=", name).executeTakeFirst();
	return Number(result.numDeletedRows ?? 0n);
}
/**
* Resolve a raw API token (ec_pat_...) to a user ID and scopes.
* Updates last_used_at on successful lookup.
* Returns null if the token is invalid or expired.
*/
async function resolveApiToken(db, rawToken) {
	const hash = hashApiToken(rawToken);
	const row = await db.selectFrom("_emdash_api_tokens").select([
		"id",
		"user_id",
		"scopes",
		"expires_at"
	]).where("token_hash", "=", hash).executeTakeFirst();
	if (!row) return null;
	if (row.expires_at && new Date(row.expires_at) < /* @__PURE__ */ new Date()) return null;
	db.updateTable("_emdash_api_tokens").set({ last_used_at: (/* @__PURE__ */ new Date()).toISOString() }).where("id", "=", row.id).execute().catch(() => {});
	return {
		userId: row.user_id,
		scopes: JSON.parse(row.scopes)
	};
}
/**
* Resolve an OAuth access token (ec_oat_...) to a user ID and scopes.
* Returns null if the token is invalid or expired.
*/
async function resolveOAuthToken(db, rawToken) {
	const hash = hashApiToken(rawToken);
	const row = await db.selectFrom("_emdash_oauth_tokens").select([
		"user_id",
		"scopes",
		"expires_at",
		"token_type"
	]).where("token_hash", "=", hash).where("token_type", "=", "access").executeTakeFirst();
	if (!row) return null;
	if (new Date(row.expires_at) < /* @__PURE__ */ new Date()) return null;
	return {
		userId: row.user_id,
		scopes: JSON.parse(row.scopes)
	};
}

//#endregion
export { resolveApiToken as a, handleApiTokenRevoke as i, handleApiTokenCreate as n, resolveOAuthToken as o, handleApiTokenList as r, deleteApiTokensByName as t };
//# sourceMappingURL=api-tokens-DvqeZmVq.mjs.map