feat: implement AI styling foundation and billing scope rework
This commit is contained in:
142
resources/js/guest-v2/services/aiEditsApi.ts
Normal file
142
resources/js/guest-v2/services/aiEditsApi.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { fetchJson } from './apiClient';
|
||||
import { getDeviceId } from '../lib/device';
|
||||
|
||||
export type GuestAiStyle = {
|
||||
id: number;
|
||||
key: string;
|
||||
name: string;
|
||||
category?: string | null;
|
||||
description?: string | null;
|
||||
provider?: string | null;
|
||||
provider_model?: string | null;
|
||||
requires_source_image?: boolean;
|
||||
is_premium?: boolean;
|
||||
metadata?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type GuestAiStylesMeta = {
|
||||
required_feature?: string | null;
|
||||
addon_keys?: string[] | null;
|
||||
allow_custom_prompt?: boolean;
|
||||
allowed_style_keys?: string[] | null;
|
||||
policy_message?: string | null;
|
||||
};
|
||||
|
||||
export type GuestAiEditOutput = {
|
||||
id: number;
|
||||
storage_disk?: string | null;
|
||||
storage_path?: string | null;
|
||||
provider_url?: string | null;
|
||||
mime_type?: string | null;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
is_primary?: boolean;
|
||||
safety_state?: string | null;
|
||||
safety_reasons?: string[];
|
||||
generated_at?: string | null;
|
||||
};
|
||||
|
||||
export type GuestAiEditRequest = {
|
||||
id: number;
|
||||
event_id: number;
|
||||
photo_id: number;
|
||||
style?: {
|
||||
id: number;
|
||||
key: string;
|
||||
name: string;
|
||||
} | null;
|
||||
provider?: string | null;
|
||||
provider_model?: string | null;
|
||||
status: 'queued' | 'processing' | 'succeeded' | 'failed' | 'blocked' | 'canceled' | string;
|
||||
safety_state?: string | null;
|
||||
safety_reasons?: string[];
|
||||
failure_code?: string | null;
|
||||
failure_message?: string | null;
|
||||
queued_at?: string | null;
|
||||
started_at?: string | null;
|
||||
completed_at?: string | null;
|
||||
outputs: GuestAiEditOutput[];
|
||||
};
|
||||
|
||||
export type GuestAiStylesResponse = {
|
||||
data: GuestAiStyle[];
|
||||
meta: GuestAiStylesMeta;
|
||||
};
|
||||
|
||||
export type GuestAiEditEnvelope = {
|
||||
message?: string;
|
||||
duplicate?: boolean;
|
||||
data: GuestAiEditRequest;
|
||||
};
|
||||
|
||||
function deviceHeaders(): Record<string, string> {
|
||||
return {
|
||||
'X-Device-Id': getDeviceId(),
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchGuestAiStyles(eventToken: string): Promise<GuestAiStylesResponse> {
|
||||
const response = await fetchJson<GuestAiStylesResponse>(
|
||||
`/api/v1/events/${encodeURIComponent(eventToken)}/ai-styles`,
|
||||
{
|
||||
headers: deviceHeaders(),
|
||||
noStore: true,
|
||||
}
|
||||
);
|
||||
|
||||
const payload = response.data;
|
||||
|
||||
return {
|
||||
data: Array.isArray(payload?.data) ? payload.data : [],
|
||||
meta: payload?.meta && typeof payload.meta === 'object' ? payload.meta : {},
|
||||
};
|
||||
}
|
||||
|
||||
export async function createGuestAiEdit(
|
||||
eventToken: string,
|
||||
photoId: number,
|
||||
payload: {
|
||||
style_key?: string;
|
||||
prompt?: string;
|
||||
negative_prompt?: string;
|
||||
provider_model?: string;
|
||||
idempotency_key?: string;
|
||||
session_id?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
): Promise<GuestAiEditEnvelope> {
|
||||
const response = await fetchJson<GuestAiEditEnvelope>(
|
||||
`/api/v1/events/${encodeURIComponent(eventToken)}/photos/${photoId}/ai-edits`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...deviceHeaders(),
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
noStore: true,
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.data || typeof response.data !== 'object' || !response.data.data) {
|
||||
throw new Error('AI edit request response is invalid.');
|
||||
}
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function fetchGuestAiEditStatus(eventToken: string, requestId: number): Promise<{ data: GuestAiEditRequest }> {
|
||||
const response = await fetchJson<{ data: GuestAiEditRequest }>(
|
||||
`/api/v1/events/${encodeURIComponent(eventToken)}/ai-edits/${requestId}`,
|
||||
{
|
||||
headers: deviceHeaders(),
|
||||
noStore: true,
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.data || typeof response.data !== 'object' || !response.data.data) {
|
||||
throw new Error('AI edit status response is invalid.');
|
||||
}
|
||||
|
||||
return response.data;
|
||||
}
|
||||
Reference in New Issue
Block a user