release: WRNexusJS 0.4.0

This commit is contained in:
2026-07-27 12:42:18 +05:30
parent 8b728a3e5d
commit 30e5721e84
250 changed files with 10065 additions and 3923 deletions
+23 -11
View File
@@ -1,8 +1,4 @@
import type {
CaptchaChallengeRecord,
CaptchaResponseTokenRecord,
CaptchaStore,
} from "../types.ts";
import type { CaptchaChallengeRecord, CaptchaResponseTokenRecord, CaptchaStore } from "../types.ts";
export interface SqliteStatementLike {
run(...params: unknown[]): unknown;
@@ -21,16 +17,21 @@ export interface SqliteCaptchaStoreOptions {
}
function safeIdentifier(value: string): string {
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) throw new TypeError(`Unsafe SQL identifier: ${value}`);
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value))
throw new TypeError(`Unsafe SQL identifier: ${value}`);
return value;
}
function parseChallenge(row: Record<string, unknown> | undefined): CaptchaChallengeRecord | undefined {
function parseChallenge(
row: Record<string, unknown> | undefined,
): CaptchaChallengeRecord | undefined {
if (!row) return undefined;
return JSON.parse(String(row.payload)) as CaptchaChallengeRecord;
}
function parseToken(row: Record<string, unknown> | undefined): CaptchaResponseTokenRecord | undefined {
function parseToken(
row: Record<string, unknown> | undefined,
): CaptchaResponseTokenRecord | undefined {
if (!row) return undefined;
return JSON.parse(String(row.payload)) as CaptchaResponseTokenRecord;
}
@@ -77,7 +78,13 @@ export class SqliteCaptchaStore implements CaptchaStore {
(id, payload, expires_at, consumed_at, attempts)
VALUES (?, ?, ?, ?, ?)`,
)
.run(record.id, JSON.stringify(record), record.expiresAt, record.consumedAt ?? null, record.attempts);
.run(
record.id,
JSON.stringify(record),
record.expiresAt,
record.consumedAt ?? null,
record.attempts,
);
}
async getChallenge(id: string): Promise<CaptchaChallengeRecord | undefined> {
@@ -96,7 +103,9 @@ export class SqliteCaptchaStore implements CaptchaStore {
SET payload = ?, attempts = ?
WHERE id = ? AND expires_at > ? AND consumed_at IS NULL AND attempts = ?`,
)
.run(JSON.stringify(current), current.attempts, id, now, current.attempts - 1) as { changes?: number };
.run(JSON.stringify(current), current.attempts, id, now, current.attempts - 1) as {
changes?: number;
};
return result?.changes === 0 ? undefined : current;
}
@@ -134,7 +143,10 @@ export class SqliteCaptchaStore implements CaptchaStore {
);
}
async consumeToken(tokenHash: string, now: number): Promise<CaptchaResponseTokenRecord | undefined> {
async consumeToken(
tokenHash: string,
now: number,
): Promise<CaptchaResponseTokenRecord | undefined> {
const current = await this.getToken(tokenHash);
if (!current || current.expiresAt <= now || current.consumedAt) return undefined;
current.consumedAt = now;