Add Prettier and ESLint tooling (Refs #77)

This commit is contained in:
2026-10-09 15:56:13 -04:00
parent 8ed059b8d3
commit 16469e2d43
711 changed files with 99737 additions and 28286 deletions
+118 -46
View File
@@ -15,7 +15,12 @@ function validGame(game: unknown): asserts game is KeyGame {
}
function normalizedKey(key: unknown): string {
if (typeof key !== 'string' || !key.trim() || key.trim().length > 512 || /\s/.test(key.trim())) {
if (
typeof key !== 'string' ||
!key.trim() ||
key.trim().length > 512 ||
/\s/.test(key.trim())
) {
throw new Error('Enter a server key without whitespace (maximum 512 characters)');
}
return key.trim();
@@ -29,22 +34,34 @@ function normalizedLabel(label: unknown): string {
}
export function listServerKeys(): ServerKey[] {
const rows = db().prepare('SELECT id,game,label,updated_at FROM server_keys ORDER BY game,label,id').all() as Omit<ServerKey, 'assigned_servers'>[];
const assignments = db().prepare(`SELECT DISTINCT k.id AS key_id,l.server_id FROM server_keys k
const rows = db()
.prepare('SELECT id,game,label,updated_at FROM server_keys ORDER BY game,label,id')
.all() as Omit<ServerKey, 'assigned_servers'>[];
const assignments = db()
.prepare(
`SELECT DISTINCT k.id AS key_id,l.server_id FROM server_keys k
JOIN server_keys occupied ON occupied.pluto_key=k.pluto_key JOIN server_key_leases l ON l.key_id=occupied.id
ORDER BY l.server_id`).all() as { key_id: string; server_id: string }[];
ORDER BY l.server_id`
)
.all() as { key_id: string; server_id: string }[];
const byKey = new Map<string, string[]>();
for (const lease of assignments) {
const servers = byKey.get(lease.key_id) ?? [];
servers.push(lease.server_id);
byKey.set(lease.key_id, servers);
}
return rows.map(row => ({ ...row, assigned_servers: byKey.get(row.id) ?? [] }));
return rows.map((row) => ({ ...row, assigned_servers: byKey.get(row.id) ?? [] }));
}
export function getServerKey(serverId: string): string | undefined {
return (db().prepare(`SELECT k.pluto_key FROM server_key_leases l
JOIN server_keys k ON k.id=l.key_id WHERE l.server_id=? AND l.is_current=1`).get(serverId) as { pluto_key: string } | undefined)?.pluto_key;
return (
db()
.prepare(
`SELECT k.pluto_key FROM server_key_leases l
JOIN server_keys k ON k.id=l.key_id WHERE l.server_id=? AND l.is_current=1`
)
.get(serverId) as { pluto_key: string } | undefined
)?.pluto_key;
}
/** Saving a credential twice cannot increase available capacity. */
@@ -52,16 +69,27 @@ export function saveServerKey(game: unknown, key: unknown, label?: unknown): str
validGame(game);
const credential = normalizedKey(key);
const keyLabel = label === undefined ? undefined : normalizedLabel(label);
return db().transaction(() => {
const existing = db().prepare('SELECT id FROM server_keys WHERE game=? AND pluto_key=?').get(game, credential) as { id: string } | undefined;
if (existing) {
if (keyLabel !== undefined) db().prepare("UPDATE server_keys SET label=?,updated_at=datetime('now') WHERE id=?").run(keyLabel, existing.id);
return existing.id;
}
const id = randomUUID();
db().prepare('INSERT INTO server_keys(id,game,label,pluto_key) VALUES(?,?,?,?)').run(id, game, keyLabel ?? '', credential);
return id;
}).immediate();
return db()
.transaction(() => {
const existing = db()
.prepare('SELECT id FROM server_keys WHERE game=? AND pluto_key=?')
.get(game, credential) as { id: string } | undefined;
if (existing) {
if (keyLabel !== undefined)
db()
.prepare(
"UPDATE server_keys SET label=?,updated_at=datetime('now') WHERE id=?"
)
.run(keyLabel, existing.id);
return existing.id;
}
const id = randomUUID();
db()
.prepare('INSERT INTO server_keys(id,game,label,pluto_key) VALUES(?,?,?,?)')
.run(id, game, keyLabel ?? '', credential);
return id;
})
.immediate();
}
// Compare the credential as well as its row: a mistakenly imported copy in
@@ -70,11 +98,18 @@ const availableKey = `NOT EXISTS (SELECT 1 FROM server_key_leases l
JOIN server_keys occupied ON occupied.id=l.key_id
WHERE occupied.pluto_key=k.pluto_key AND (l.server_id!=@server OR l.is_current=0))`;
export function serverKeyPool(game: KeyGame, serverId?: string): { total: number; available: number } {
export function serverKeyPool(
game: KeyGame,
serverId?: string
): { total: number; available: number } {
validGame(game);
return db().prepare(`SELECT COUNT(*) AS total,
return db()
.prepare(
`SELECT COUNT(*) AS total,
COALESCE(SUM(CASE WHEN ${availableKey} THEN 1 ELSE 0 END),0) AS available
FROM server_keys k WHERE k.game=@game`).get({ game, server: serverId ?? '' }) as { total: number; available: number };
FROM server_keys k WHERE k.game=@game`
)
.get({ game, server: serverId ?? '' }) as { total: number; available: number };
}
export function availableServerKeyCount(game: KeyGame): number {
@@ -85,38 +120,75 @@ export function availableServerKeyCount(game: KeyGame): number {
export function reserveServerKey(serverId: string, game: KeyGame, suppliedKey?: unknown): string {
validGame(game);
if (!serverId) throw new Error('Choose a server for the key reservation');
const credential = suppliedKey === undefined || suppliedKey === null || (typeof suppliedKey === 'string' && !suppliedKey.trim())
? undefined : normalizedKey(suppliedKey);
return db().transaction(() => {
const existing = db().prepare(`SELECT k.game,k.pluto_key FROM server_key_leases l
JOIN server_keys k ON k.id=l.key_id WHERE l.server_id=? AND l.is_current=1`).get(serverId) as { game: KeyGame; pluto_key: string } | undefined;
if (existing) {
if (existing.game !== game) throw new Error('This server already has a key reserved for another game');
if (credential && credential !== existing.pluto_key) throw new Error('This server already has a reserved key; destroy it before changing its key');
return existing.pluto_key;
}
const requestedId = credential ? saveServerKey(game, credential) : null;
const key = db().prepare(`SELECT k.id,k.pluto_key FROM server_keys k WHERE k.game=@game
const credential =
suppliedKey === undefined ||
suppliedKey === null ||
(typeof suppliedKey === 'string' && !suppliedKey.trim())
? undefined
: normalizedKey(suppliedKey);
return db()
.transaction(() => {
const existing = db()
.prepare(
`SELECT k.game,k.pluto_key FROM server_key_leases l
JOIN server_keys k ON k.id=l.key_id WHERE l.server_id=? AND l.is_current=1`
)
.get(serverId) as { game: KeyGame; pluto_key: string } | undefined;
if (existing) {
if (existing.game !== game)
throw new Error('This server already has a key reserved for another game');
if (credential && credential !== existing.pluto_key)
throw new Error(
'This server already has a reserved key; destroy it before changing its key'
);
return existing.pluto_key;
}
const requestedId = credential ? saveServerKey(game, credential) : null;
const key = db()
.prepare(
`SELECT k.id,k.pluto_key FROM server_keys k WHERE k.game=@game
AND (@requestedId IS NULL OR k.id=@requestedId) AND ${availableKey}
ORDER BY k.updated_at,k.id LIMIT 1`).get({ game, server: serverId, requestedId }) as { id: string; pluto_key: string } | undefined;
if (!key) throw new Error(credential ? 'This server key is already reserved by another server'
: `No available ${game.toUpperCase()} server keys. Add a key or destroy a server to release one.`);
db().prepare('INSERT INTO server_key_leases(server_id,key_id) VALUES(?,?)').run(serverId, key.id);
return key.pluto_key;
}).immediate();
ORDER BY k.updated_at,k.id LIMIT 1`
)
.get({ game, server: serverId, requestedId }) as
{ id: string; pluto_key: string } | undefined;
if (!key)
throw new Error(
credential
? 'This server key is already reserved by another server'
: `No available ${game.toUpperCase()} server keys. Add a key or destroy a server to release one.`
);
db()
.prepare('INSERT INTO server_key_leases(server_id,key_id) VALUES(?,?)')
.run(serverId, key.id);
return key.pluto_key;
})
.immediate();
}
/** Only after confirmed destruction or a creation cancelled before any host mutation. */
export function releaseServerKey(serverId: string): boolean {
return db().prepare('DELETE FROM server_key_leases WHERE server_id=?').run(serverId).changes > 0;
return (
db().prepare('DELETE FROM server_key_leases WHERE server_id=?').run(serverId).changes > 0
);
}
export function removeServerKey(id: string): boolean {
return db().transaction(() => {
if (db().prepare(`SELECT 1 FROM server_keys k JOIN server_keys occupied ON occupied.pluto_key=k.pluto_key
JOIN server_key_leases l ON l.key_id=occupied.id WHERE k.id=?`).get(id)) {
throw new Error('This key is reserved by a server. Destroy that server before removing its key.');
}
return db().prepare('DELETE FROM server_keys WHERE id=?').run(id).changes > 0;
}).immediate();
return db()
.transaction(() => {
if (
db()
.prepare(
`SELECT 1 FROM server_keys k JOIN server_keys occupied ON occupied.pluto_key=k.pluto_key
JOIN server_key_leases l ON l.key_id=occupied.id WHERE k.id=?`
)
.get(id)
) {
throw new Error(
'This key is reserved by a server. Destroy that server before removing its key.'
);
}
return db().prepare('DELETE FROM server_keys WHERE id=?').run(id).changes > 0;
})
.immediate();
}