mirror of
https://github.com/fluxerapp/fluxer.git
synced 2026-09-02 21:04:06 +03:00
fix(ci): clear knip, refresh openapi, close kv schema race (#2409)
This commit is contained in:
@@ -374,6 +374,10 @@ suite('postgres kv upgrade safety', () => {
|
|||||||
const gate = new Promise<void>((resolve) => {
|
const gate = new Promise<void>((resolve) => {
|
||||||
release = resolve;
|
release = resolve;
|
||||||
});
|
});
|
||||||
|
let created = () => {};
|
||||||
|
const tableCreated = new Promise<void>((resolve) => {
|
||||||
|
created = resolve;
|
||||||
|
});
|
||||||
const peer = raw.transaction(async (db) => {
|
const peer = raw.transaction(async (db) => {
|
||||||
await db.query(`
|
await db.query(`
|
||||||
CREATE TABLE IF NOT EXISTS ${RACE} (
|
CREATE TABLE IF NOT EXISTS ${RACE} (
|
||||||
@@ -385,13 +389,22 @@ CREATE TABLE IF NOT EXISTS ${RACE} (
|
|||||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||||
PRIMARY KEY (table_name, row_key)
|
PRIMARY KEY (table_name, row_key)
|
||||||
)`);
|
)`);
|
||||||
|
created();
|
||||||
await gate;
|
await gate;
|
||||||
});
|
});
|
||||||
|
await Promise.race([tableCreated, peer]);
|
||||||
const booting = ensurePostgresKvSchema(new TableClient(raw, RACE)).then(
|
const booting = ensurePostgresKvSchema(new TableClient(raw, RACE)).then(
|
||||||
() => 'ok',
|
() => 'ok',
|
||||||
(error: Error) => `failed: ${error.message}`,
|
(error: Error) => `failed: ${error.message}`,
|
||||||
);
|
);
|
||||||
await sleep(500);
|
for (let attempt = 0; attempt < 200; attempt += 1) {
|
||||||
|
const blocked = await raw.query(
|
||||||
|
`SELECT 1 FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND wait_event_type = 'Lock' AND query LIKE $1`,
|
||||||
|
[`%${RACE}%`],
|
||||||
|
);
|
||||||
|
if (blocked.rows.length > 0) break;
|
||||||
|
await sleep(50);
|
||||||
|
}
|
||||||
release();
|
release();
|
||||||
await peer;
|
await peer;
|
||||||
expect(await booting).toBe('ok');
|
expect(await booting).toBe('ok');
|
||||||
|
|||||||
@@ -486,7 +486,11 @@
|
|||||||
"description": "Cancel an ongoing handoff session. The handoff code will no longer be valid for authentication.",
|
"description": "Cancel an ongoing handoff session. The handoff code will no longer be valid for authentication.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"}
|
{"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"}
|
||||||
]
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HandoffCancelRequest"}}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/auth/handoff/{code}/info": {
|
"/auth/handoff/{code}/info": {
|
||||||
@@ -609,6 +613,69 @@
|
|||||||
"parameters": [
|
"parameters": [
|
||||||
{"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"}
|
{"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"operationId": "get_handoff_status_with_secret",
|
||||||
|
"summary": "Get handoff status with secret",
|
||||||
|
"tags": ["Auth"],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HandoffStatusResponse"}}}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request - The request was malformed or contained invalid data",
|
||||||
|
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
|
||||||
|
},
|
||||||
|
"429": {
|
||||||
|
"description": "Too Many Requests - You are being rate limited",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"code": {"type": "string", "enum": ["RATE_LIMITED"]},
|
||||||
|
"message": {"type": "string"},
|
||||||
|
"retry_after": {"type": "number", "description": "Seconds to wait before retrying"},
|
||||||
|
"global": {"type": "boolean", "description": "Whether this is a global rate limit"}
|
||||||
|
},
|
||||||
|
"required": ["code", "message", "retry_after"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"Retry-After": {
|
||||||
|
"description": "Number of seconds to wait before retrying (only on 429)",
|
||||||
|
"schema": {"type": "integer"}
|
||||||
|
},
|
||||||
|
"X-RateLimit-Limit": {
|
||||||
|
"description": "The number of requests that can be made in the current window",
|
||||||
|
"schema": {"type": "integer"}
|
||||||
|
},
|
||||||
|
"X-RateLimit-Remaining": {
|
||||||
|
"description": "The number of remaining requests that can be made",
|
||||||
|
"schema": {"type": "integer"}
|
||||||
|
},
|
||||||
|
"X-RateLimit-Reset": {
|
||||||
|
"description": "Unix timestamp when the rate limit resets",
|
||||||
|
"schema": {"type": "integer"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error - An unexpected error occurred",
|
||||||
|
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-mint": {"metadata": {"title": "Get handoff status with secret"}},
|
||||||
|
"description": "Check the status of a handoff session using the poll secret from initiation. Returns the authentication token once the handoff is complete and the presented secret matches.",
|
||||||
|
"parameters": [
|
||||||
|
{"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HandoffStatusRequest"}}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/auth/ip-authorization/poll": {
|
"/auth/ip-authorization/poll": {
|
||||||
@@ -23871,10 +23938,21 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time",
|
"format": "date-time",
|
||||||
"description": "ISO 8601 timestamp when the handoff code expires"
|
"description": "ISO 8601 timestamp when the handoff code expires"
|
||||||
|
},
|
||||||
|
"poll_secret": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Secret the initiating device must present to retrieve the token"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["code", "expires_at"]
|
"required": ["code", "expires_at"]
|
||||||
},
|
},
|
||||||
|
"HandoffCancelRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"poll_secret": {"type": "string", "description": "The poll secret issued when the handoff was initiated"}
|
||||||
|
},
|
||||||
|
"required": ["poll_secret"]
|
||||||
|
},
|
||||||
"HandoffInfoResponse": {
|
"HandoffInfoResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -23981,6 +24059,13 @@
|
|||||||
},
|
},
|
||||||
"required": ["id", "username", "discriminator", "global_name", "avatar", "avatar_color", "flags"]
|
"required": ["id", "username", "discriminator", "global_name", "avatar", "avatar_color", "flags"]
|
||||||
},
|
},
|
||||||
|
"HandoffStatusRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"poll_secret": {"type": "string", "description": "The poll secret issued when the handoff was initiated"}
|
||||||
|
},
|
||||||
|
"required": ["poll_secret"]
|
||||||
|
},
|
||||||
"IpAuthorizationPollResponse": {
|
"IpAuthorizationPollResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -31264,9 +31349,9 @@
|
|||||||
"page": {
|
"page": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
"maximum": 9007199254740991,
|
"maximum": 400,
|
||||||
"format": "int53",
|
"format": "int32",
|
||||||
"description": "Page number for pagination (ignored when cursor is provided)"
|
"description": "Page number for pagination (ignored when cursor is provided). Use cursor to page beyond this."
|
||||||
},
|
},
|
||||||
"cursor": {
|
"cursor": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
@@ -32178,12 +32263,7 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {"type": "string", "enum": ["bsky", "domain"], "description": "The type of connection to create"},
|
"type": {"type": "string", "enum": ["bsky", "domain"], "description": "The type of connection to create"},
|
||||||
"identifier": {
|
"identifier": {"type": "string", "description": "The connection identifier (handle or domain)"},
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 253,
|
|
||||||
"description": "The connection identifier (handle or domain)"
|
|
||||||
},
|
|
||||||
"visibility_flags": {"$ref": "#/components/schemas/Int32Type"}
|
"visibility_flags": {"$ref": "#/components/schemas/Int32Type"}
|
||||||
},
|
},
|
||||||
"required": ["type", "identifier"]
|
"required": ["type", "identifier"]
|
||||||
|
|||||||
@@ -229,7 +229,6 @@
|
|||||||
"mobx-persist-store": "catalog:",
|
"mobx-persist-store": "catalog:",
|
||||||
"mobx-react-lite": "catalog:",
|
"mobx-react-lite": "catalog:",
|
||||||
"motion": "catalog:",
|
"motion": "catalog:",
|
||||||
"onnxruntime-common": "catalog:",
|
|
||||||
"onnxruntime-web": "catalog:",
|
"onnxruntime-web": "catalog:",
|
||||||
"qrcode": "catalog:",
|
"qrcode": "catalog:",
|
||||||
"react": "catalog:",
|
"react": "catalog:",
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ interface PinnedAddress {
|
|||||||
readonly family: 4 | 6;
|
readonly family: 4 | 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DesktopOutboundGETRequest {
|
interface DesktopOutboundGETRequest {
|
||||||
readonly context: string;
|
readonly context: string;
|
||||||
readonly timeoutMs: number;
|
readonly timeoutMs: number;
|
||||||
readonly url: URL;
|
readonly url: URL;
|
||||||
@@ -69,42 +69,42 @@ interface BoundedMessageRead {
|
|||||||
readonly message: Readable;
|
readonly message: Readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DesktopOutboundHTTPBlockedError extends Error {
|
class DesktopOutboundHTTPBlockedError extends Error {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super(DESKTOP_OUTBOUND_HTTP_BLOCKED_MESSAGE);
|
super(DESKTOP_OUTBOUND_HTTP_BLOCKED_MESSAGE);
|
||||||
this.name = 'DesktopOutboundHTTPBlockedError';
|
this.name = 'DesktopOutboundHTTPBlockedError';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DesktopOutboundHTTPTransportError extends Error {
|
class DesktopOutboundHTTPTransportError extends Error {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super(DESKTOP_OUTBOUND_HTTP_TRANSPORT_MESSAGE);
|
super(DESKTOP_OUTBOUND_HTTP_TRANSPORT_MESSAGE);
|
||||||
this.name = 'DesktopOutboundHTTPTransportError';
|
this.name = 'DesktopOutboundHTTPTransportError';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DesktopOutboundHTTPTimeoutError extends Error {
|
class DesktopOutboundHTTPTimeoutError extends Error {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super(DESKTOP_OUTBOUND_HTTP_TIMEOUT_MESSAGE);
|
super(DESKTOP_OUTBOUND_HTTP_TIMEOUT_MESSAGE);
|
||||||
this.name = 'DesktopOutboundHTTPTimeoutError';
|
this.name = 'DesktopOutboundHTTPTimeoutError';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DesktopOutboundHTTPCapacityError extends Error {
|
class DesktopOutboundHTTPCapacityError extends Error {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super(DESKTOP_OUTBOUND_HTTP_CAPACITY_MESSAGE);
|
super(DESKTOP_OUTBOUND_HTTP_CAPACITY_MESSAGE);
|
||||||
this.name = 'DesktopOutboundHTTPCapacityError';
|
this.name = 'DesktopOutboundHTTPCapacityError';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BoundedMessageByteLimitError extends RangeError {
|
class BoundedMessageByteLimitError extends RangeError {
|
||||||
public constructor(description: string, maxBytes: number) {
|
public constructor(description: string, maxBytes: number) {
|
||||||
super(`${description} exceeds ${maxBytes} bytes`);
|
super(`${description} exceeds ${maxBytes} bytes`);
|
||||||
this.name = 'BoundedMessageByteLimitError';
|
this.name = 'BoundedMessageByteLimitError';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BoundedMessageChunkLimitError extends RangeError {
|
class BoundedMessageChunkLimitError extends RangeError {
|
||||||
public constructor(description: string, maxChunks: number) {
|
public constructor(description: string, maxChunks: number) {
|
||||||
super(`${description} exceeds ${maxChunks} response chunks`);
|
super(`${description} exceeds ${maxChunks} response chunks`);
|
||||||
this.name = 'BoundedMessageChunkLimitError';
|
this.name = 'BoundedMessageChunkLimitError';
|
||||||
@@ -269,7 +269,7 @@ function isPublicIPv6Address(address: string): boolean {
|
|||||||
return !(first === 0x2001 && second === 0x0db8);
|
return !(first === 0x2001 && second === 0x0db8);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPublicPinnedAddress(pinned: PinnedAddress): boolean {
|
function isPublicPinnedAddress(pinned: PinnedAddress): boolean {
|
||||||
return pinned.family === 4 ? isPublicIPv4Address(pinned.address) : isPublicIPv6Address(pinned.address);
|
return pinned.family === 4 ? isPublicIPv4Address(pinned.address) : isPublicIPv6Address(pinned.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +396,7 @@ async function lookupAllAddresses(hostname: string): Promise<ReadonlyArray<strin
|
|||||||
return records.map((record) => record.address);
|
return records.map((record) => record.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DesktopOutboundHTTP {
|
class DesktopOutboundHTTP {
|
||||||
private readonly httpAgent = new http.Agent({keepAlive: true, maxSockets: DESKTOP_OUTBOUND_HTTP_MAX_SOCKETS});
|
private readonly httpAgent = new http.Agent({keepAlive: true, maxSockets: DESKTOP_OUTBOUND_HTTP_MAX_SOCKETS});
|
||||||
private readonly httpsAgent = new https.Agent({keepAlive: true, maxSockets: DESKTOP_OUTBOUND_HTTP_MAX_SOCKETS});
|
private readonly httpsAgent = new https.Agent({keepAlive: true, maxSockets: DESKTOP_OUTBOUND_HTTP_MAX_SOCKETS});
|
||||||
private addressRequirementOperation: Promise<DesktopAddressRequirement> | null = null;
|
private addressRequirementOperation: Promise<DesktopAddressRequirement> | null = null;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import {isTrustedOrigin} from '@electron/main/Window';
|
import {isTrustedOrigin} from '@electron/main/Window';
|
||||||
import type {IpcMainInvokeEvent} from 'electron';
|
import type {IpcMainInvokeEvent} from 'electron';
|
||||||
|
|
||||||
export class UntrustedRendererDocumentSenderError extends Error {
|
class UntrustedRendererDocumentSenderError extends Error {
|
||||||
public constructor(channel: string) {
|
public constructor(channel: string) {
|
||||||
super(`${channel} is only reachable from a trusted top-level renderer document`);
|
super(`${channel} is only reachable from a trusted top-level renderer document`);
|
||||||
this.name = 'UntrustedRendererDocumentSenderError';
|
this.name = 'UntrustedRendererDocumentSenderError';
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ function normalizeDesktopHandoffCode(value: string): string {
|
|||||||
return value.replace(DESKTOP_HANDOFF_CODE_SEPARATOR_PATTERN, '').toUpperCase();
|
return value.replace(DESKTOP_HANDOFF_CODE_SEPARATOR_PATTERN, '').toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isDesktopHandoffCode(value: string): boolean {
|
function isDesktopHandoffCode(value: string): boolean {
|
||||||
if (value.length !== DESKTOP_HANDOFF_CODE_LENGTH) {
|
if (value.length !== DESKTOP_HANDOFF_CODE_LENGTH) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Array.from(value).every((character) => DESKTOP_HANDOFF_CODE_ALPHABET.includes(character));
|
return Array.from(value).every((character) => DESKTOP_HANDOFF_CODE_ALPHABET.includes(character));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseDesktopHandoffCodeInput(value: string): string {
|
function parseDesktopHandoffCodeInput(value: string): string {
|
||||||
return normalizeDesktopHandoffCode(value).slice(0, DESKTOP_HANDOFF_CODE_LENGTH);
|
return normalizeDesktopHandoffCode(value).slice(0, DESKTOP_HANDOFF_CODE_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
-6
@@ -267,9 +267,6 @@ catalogs:
|
|||||||
nodemailer:
|
nodemailer:
|
||||||
specifier: 9.0.6
|
specifier: 9.0.6
|
||||||
version: 9.0.6
|
version: 9.0.6
|
||||||
onnxruntime-common:
|
|
||||||
specifier: 1.27.0
|
|
||||||
version: 1.27.0
|
|
||||||
onnxruntime-web:
|
onnxruntime-web:
|
||||||
specifier: 1.27.0
|
specifier: 1.27.0
|
||||||
version: 1.27.0
|
version: 1.27.0
|
||||||
@@ -1535,9 +1532,6 @@ importers:
|
|||||||
motion:
|
motion:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
onnxruntime-common:
|
|
||||||
specifier: 'catalog:'
|
|
||||||
version: 1.27.0
|
|
||||||
onnxruntime-web:
|
onnxruntime-web:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 1.27.0
|
version: 1.27.0
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ catalog:
|
|||||||
msw: 2.12.10
|
msw: 2.12.10
|
||||||
nats: 2.29.3
|
nats: 2.29.3
|
||||||
nodemailer: 9.0.6
|
nodemailer: 9.0.6
|
||||||
onnxruntime-common: 1.27.0
|
|
||||||
onnxruntime-web: 1.27.0
|
onnxruntime-web: 1.27.0
|
||||||
pg: 8.16.3
|
pg: 8.16.3
|
||||||
pino: 10.3.1
|
pino: 10.3.1
|
||||||
|
|||||||
Reference in New Issue
Block a user