regenerate api

This commit is contained in:
Igor Loskutov
2026-02-06 14:02:08 -05:00
parent 08462338de
commit f6594448e6
3 changed files with 254 additions and 14 deletions

View File

@@ -27,6 +27,7 @@ import {
useMeetingStartRecording, useMeetingStartRecording,
useMeetingJoining, useMeetingJoining,
useMeetingJoined, useMeetingJoined,
buildMeetingLeaveUrl,
} from "../../lib/apiHooks"; } from "../../lib/apiHooks";
import { omit } from "remeda"; import { omit } from "remeda";
import { import {
@@ -251,7 +252,7 @@ export default function DailyRoom({ meeting, room }: DailyRoomProps) {
const handleBeforeUnload = () => { const handleBeforeUnload = () => {
// sendBeacon guarantees delivery even if tab closes mid-request // sendBeacon guarantees delivery even if tab closes mid-request
const url = `/v1/rooms/${roomName}/meetings/${meeting.id}/leave`; const url = buildMeetingLeaveUrl(roomName, meeting.id);
navigator.sendBeacon(url, JSON.stringify({})); navigator.sendBeacon(url, JSON.stringify({}));
}; };

View File

@@ -1,9 +1,10 @@
"use client"; "use client";
import { $api } from "./apiClient"; import { createFinalURL, createQuerySerializer } from "openapi-fetch";
import { $api, API_URL } from "./apiClient";
import { useError } from "../(errors)/errorContext"; import { useError } from "../(errors)/errorContext";
import { QueryClient, useQueryClient } from "@tanstack/react-query"; import { QueryClient, useQueryClient } from "@tanstack/react-query";
import type { components } from "../reflector-api"; import type { components, paths } from "../reflector-api";
import { useAuth } from "./AuthProvider"; import { useAuth } from "./AuthProvider";
import { MeetingId } from "./types"; import { MeetingId } from "./types";
import { NonEmptyString } from "./utils"; import { NonEmptyString } from "./utils";
@@ -14,6 +15,10 @@ import { NonEmptyString } from "./utils";
* or, limitation or incorrect usage of .d type generator from json schema * or, limitation or incorrect usage of .d type generator from json schema
* */ * */
/*
if you experience lack of expected endpoints on $api, try to regenerate
*/
export const useAuthReady = () => { export const useAuthReady = () => {
const auth = useAuth(); const auth = useAuth();
@@ -807,35 +812,47 @@ export function useRoomJoinMeeting() {
); );
} }
// Presence race fix endpoints (not yet in OpenAPI spec) // Presence race fix endpoints - signal join intent to prevent race conditions during WebRTC handshake
// These signal join intent to prevent race conditions during WebRTC handshake export function useMeetingJoining() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any return $api.useMutation(
export function useMeetingJoining(): any {
return ($api as any).useMutation(
"post", "post",
"/v1/rooms/{room_name}/meetings/{meeting_id}/joining", "/v1/rooms/{room_name}/meetings/{meeting_id}/joining",
{}, {},
); );
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any export function useMeetingJoined() {
export function useMeetingJoined(): any { return $api.useMutation(
return ($api as any).useMutation(
"post", "post",
"/v1/rooms/{room_name}/meetings/{meeting_id}/joined", "/v1/rooms/{room_name}/meetings/{meeting_id}/joined",
{}, {},
); );
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any export function useMeetingLeave() {
export function useMeetingLeave(): any { return $api.useMutation(
return ($api as any).useMutation(
"post", "post",
"/v1/rooms/{room_name}/meetings/{meeting_id}/leave", "/v1/rooms/{room_name}/meetings/{meeting_id}/leave",
{}, {},
); );
} }
/**
* Build absolute URL for /leave endpoint (for sendBeacon which can't use hooks).
*/
export function buildMeetingLeaveUrl(
roomName: string,
meetingId: string,
): string {
return createFinalURL("/v1/rooms/{room_name}/meetings/{meeting_id}/leave", {
baseUrl: API_URL,
params: {
path: { room_name: roomName, meeting_id: meetingId },
},
querySerializer: createQuerySerializer(),
});
}
export function useRoomIcsSync() { export function useRoomIcsSync() {
const { setError } = useError(); const { setError } = useError();

View File

@@ -313,6 +313,78 @@ export interface paths {
patch?: never; patch?: never;
trace?: never; trace?: never;
}; };
"/v1/rooms/{room_name}/meetings/{meeting_id}/joining": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Meeting Joining
* @description Signal intent to join meeting. Called before WebRTC handshake starts.
*
* This creates a pending join record that prevents the meeting from being
* deactivated while the WebRTC handshake is in progress. The record expires
* automatically after 30 seconds if the connection is not established.
*/
post: operations["v1_meeting_joining"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/rooms/{room_name}/meetings/{meeting_id}/joined": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Meeting Joined
* @description Signal that WebRTC connection is established.
*
* This clears the pending join record, confirming the user has successfully
* connected to the meeting. Safe to call even if meeting was deactivated
* during the handshake (idempotent cleanup).
*/
post: operations["v1_meeting_joined"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/rooms/{room_name}/meetings/{meeting_id}/leave": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Meeting Leave
* @description Trigger presence recheck when user leaves meeting.
*
* Called on tab close/navigation via sendBeacon(). Immediately queues presence
* poll to detect dirty disconnects faster than 30s periodic poll.
* Daily.co webhooks handle clean disconnects, but tab close/crash need this.
*/
post: operations["v1_meeting_leave"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/transcripts": { "/v1/transcripts": {
parameters: { parameters: {
query?: never; query?: never;
@@ -1497,6 +1569,52 @@ export interface components {
/** Reason */ /** Reason */
reason?: string | null; reason?: string | null;
}; };
/**
* JoinedRequest
* @description Request body for /joined endpoint (after WebRTC connection established).
*/
JoinedRequest: {
/**
* Connection Id
* @description A non-empty string
*/
connection_id: string;
};
/** JoinedResponse */
JoinedResponse: {
/**
* Status
* @constant
*/
status: "ok";
};
/**
* JoiningRequest
* @description Request body for /joining endpoint (before WebRTC handshake).
*/
JoiningRequest: {
/**
* Connection Id
* @description A non-empty string
*/
connection_id: string;
};
/** JoiningResponse */
JoiningResponse: {
/**
* Status
* @constant
*/
status: "ok";
};
/** LeaveResponse */
LeaveResponse: {
/**
* Status
* @constant
*/
status: "ok";
};
/** Meeting */ /** Meeting */
Meeting: { Meeting: {
/** Id */ /** Id */
@@ -2687,6 +2805,110 @@ export interface operations {
}; };
}; };
}; };
v1_meeting_joining: {
parameters: {
query?: never;
header?: never;
path: {
room_name: string;
meeting_id: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["JoiningRequest"];
};
};
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["JoiningResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
v1_meeting_joined: {
parameters: {
query?: never;
header?: never;
path: {
room_name: string;
meeting_id: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["JoinedRequest"];
};
};
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["JoinedResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
v1_meeting_leave: {
parameters: {
query?: never;
header?: never;
path: {
room_name: string;
meeting_id: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LeaveResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
v1_transcripts_list: { v1_transcripts_list: {
parameters: { parameters: {
query?: { query?: {