resources/Jobs.js

import { PollTimeout } from "../error.js";
import { constructParams } from "../util.js";
function job(j) {
    return {
        ...j,
        created: new Date(j.created),
        assets: j.assets.map((a) => ({
            ...a,
            created: new Date(a.created),
            modified: new Date(a.modified),
        }))
    };
}
/** Metafold jobs endpoint. */
export class Jobs {
    client;
    constructor(client) {
        this.client = client;
    }
    /**
     * List jobs.
     *
     * @param {Object} [params] - Optional list parameters.
     * @param {string} [params.sort] - Sort string. For details on syntax see the Metafold API docs.
     *   Supported sorting fields are: "id", "name", or "created".
     * @param {string} [params.q] - Query string. For details on syntax see the Metafold API docs.
     *   Supported search fields are: "id", "name", "type", and "state".
     * @returns List of job resources.
     */
    async list({ sort, q } = {}) {
        const params = constructParams({ sort, q });
        const r = await this.client.get(`/projects/${this.client.projectID}/jobs`, { params });
        return r.data.map(job);
    }
    /**
     * Get a job.
     *
     * @param {string} id - ID of job to get.
     * @returns Job resource.
     */
    async get(id) {
        const r = await this.client.get(`/projects/${this.client.projectID}/jobs/${id}`);
        return job(r.data);
    }
    /**
     * Dispatch a new job and wait for the result.
     *
     * See Metafold API docs for the full list of jobs.
     *
     * @param {string} type - Job type.
     * @param {Object} params - Job parameters.
     * @param {string} [name] - Job name.
     * @param {number} [timeout=12000] - Time in seconds to wait for a result.
     * @returns Completed job resource.
     */
    async run(type, params, name, timeout = 1000 * 60 * 2) {
        const url = await this.runStatus(type, params, name);
        let r = null;
        try {
            r = await this.poll(url, timeout);
        }
        catch (e) {
            if (e instanceof PollTimeout) {
                throw new Error(`Job '${name ?? type}' failed to complete within ${timeout} ms`, { cause: e });
            }
            else {
                throw e;
            }
        }
        return job(r.data);
    }
    /**
     * Dispatch a new job and return immediately without waiting for result.
     *
     * See Metafold API docs for the full list of jobs.
     *
     * @param {string} type - Job type.
     * @param {Object} params - Job parameters.
     * @param {string} [name] - Job name.
     * @returns {string} Job status url.
     */
    async runStatus(type, params, name) {
        const data = constructParams({ type, parameters: params, name });
        const r = await this.client.post(`/projects/${this.client.projectID}/jobs`, data, {
            headers: { "Content-Type": "application/json" },
        });
        return r.data.link;
    }
    /**
     * Poll the given URL every one second.
     *
     * Helpful for waiting on job results given a status URL.
     *
     * @param {string} url - Job status url.
     * @param {number} [timeout=12000] - Time in seconds to wait for a result.
     * @param {number} [every=1] - Frequency in seconds.
     * @returns HTTP response.
     */
    poll(url, timeout = 1000 * 60 * 2, every = 1) {
        return new Promise((resolve, reject) => {
            /* eslint-disable prefer-const */
            let intervalID;
            let timeoutID;
            /* eslint-enable prefer-const */
            const clearTimers = () => {
                clearInterval(intervalID);
                clearTimeout(timeoutID);
            };
            intervalID = setInterval(() => {
                this.client.get(url)
                    .then((r) => {
                    if (r.status === 202) {
                        return;
                    }
                    clearTimers();
                    resolve(r);
                })
                    .catch((e) => {
                    clearTimers();
                    reject(e);
                });
            }, 1000 * every);
            timeoutID = setTimeout(() => {
                clearInterval(intervalID);
                reject(new PollTimeout("Job timed out"));
            }, timeout);
        });
    }
    /**
     * Update a job.
     *
     * @param {string} id - ID of job to update.
     * @param {Object} [params] - Optional update parameters.
     * @param {string} [params.name] - New job name. The existing name remains unchanged if undefined.
     * @returns Updated job resource.
     */
    async update(id, { name } = {}) {
        const data = constructParams({ name });
        const r = await this.client.patch(`/projects/${this.client.projectID}/jobs/${id}`, data);
        return job(r.data);
    }
}