import { getTemporaryAuthToken } from './auth';
import { dispatchRequest } from './request';
import { storageImpl } from './storage';
import { FalStream } from './streaming';
import { EnqueueResult, QueueStatus, RequestLog } from './types';
import { ensureAppIdFormat, isUUIDv4, isValidUrl, parseAppId } from './utils';
/**
* The function input and other configuration when running
* the function, such as the HTTP method to use.
*/
type RunOptions = {
/**
* The path to the function, if any. Defaults to ``.
* @deprecated Pass the path as part of the app id itself, e.g. `fal-ai/sdxl/image-to-image`
*/
readonly path?: string;
/**
* The function input. It will be submitted either as query params
* or the body payload, depending on the `method`.
*/
readonly input?: Input;
/**
* The HTTP method, defaults to `post`;
*/
readonly method?: 'get' | 'post' | 'put' | 'delete' | string;
/**
* If `true`, the function will automatically upload any files
* (i.e. instances of `Blob`).
*
* This is enabled by default. You can disable it by setting it to `false`.
*/
readonly autoUpload?: boolean;
};
type ExtraOptions = {
/**
* If `true`, the function will use the queue to run the function
* asynchronously and return the result in a separate call. This
* influences how the URL is built.
*/
readonly subdomain?: string;
/**
* The query parameters to include in the URL.
*/
readonly query?: Record;
};
/**
* Builds the final url to run the function based on its `id` or alias and
* a the options from `RunOptions`.
*
* @private
* @param id the function id or alias
* @param options the run options
* @returns the final url to run the function
*/
export function buildUrl(
id: string,
options: RunOptions & ExtraOptions = {}
): string {
const method = (options.method ?? 'post').toLowerCase();
const path = (options.path ?? '').replace(/^\//, '').replace(/\/{2,}/, '/');
const input = options.input;
const params = {
...(options.query || {}),
...(method === 'get' ? input : {}),
};
const queryParams =
Object.keys(params).length > 0
? `?${new URLSearchParams(params).toString()}`
: '';
const parts = id.split('/');
// if a fal url is passed, just use it
if (isValidUrl(id)) {
const url = id.endsWith('/') ? id : `${id}/`;
return `${url}${path}${queryParams}`;
}
// TODO remove this after some time, fal.run should be preferred
if (parts.length === 2 && isUUIDv4(parts[1])) {
const host = 'gateway.shark.fal.ai';
return `https://${host}/trigger/${id}/${path}${queryParams}`;
}
const appId = ensureAppIdFormat(id);
const subdomain = options.subdomain ? `${options.subdomain}.` : '';
const url = `https://${subdomain}fal.run/${appId}/${path}`;
return `${url.replace(/\/$/, '')}${queryParams}`;
}
export async function send(
id: string,
options: RunOptions & ExtraOptions = {}
): Promise