un-oj
Version:
Unified Online Judge information collector.
132 lines (128 loc) • 3.72 kB
JavaScript
import { ofetch } from "ofetch";
//#region package.json
var version = "0.3.2";
//#endregion
//#region src/utils.ts
/** Get the first key of an object. */
function getFirstKey(obj) {
return Object.keys(obj)[0];
}
/**
* Parses a human-readable time string.
* @param s The string to parse.
* @returns The time in milliseconds, or undefined if failed.
*/
function parseTime(s) {
const val = Number.parseInt(s);
if (Number.isNaN(val)) return;
switch (s) {
case `${val} second`:
case `${val} seconds`:
case `${val} sec`:
case `${val} secs`: return val * 1e3;
}
}
const MEMORY_UNITS = {
megabyte: 1024 * 1024,
megabytes: 1024 * 1024,
MB: 1024 * 1024,
MiB: 1024 * 1024
};
/**
* Parses a human-readable memory size string.
*
* @param s The string to parse.
* @returns The memory size in bytes, or undefined if failed.
*/
function parseMemory(s) {
const [, val, unit] = s.match(/^(\d+) ([a-z]+)$/i) ?? [];
if (!val || !unit) return;
return Number(val) * MEMORY_UNITS[unit];
}
/**
* Adds key-value pairs to the provided headers object if they aren't present.
*
* @param h The original headers object.
* @param add The key-value pairs to add.
* @returns A **new** headers object.
*/
function addHeaders(h, add) {
if (h instanceof Headers) h = h.toJSON();
if (Array.isArray(h)) h = Object.fromEntries(h);
else if (h == null) h = {};
else h = structuredClone(h);
for (const item of add) if (!(item[0] in h)) h[item[0]] = item[1];
return h;
}
/** General error class for UnOJ. */
var UnOJError = class extends Error {};
//#endregion
//#region src/platform.ts
/**
* The base class for all platforms.
* Checkout the properties and methods to see what's available.
*
* ## Conventions
*
* - When a method is not implemented, it should throw an {@link UnsupportedError}.
* - When a resource is not found, it should throw a {@link NotFoundError}.
* - When the response is unexpected, it should throw an {@link UnexpectedResponseError}.
*/
var Platform = class {
ofetch;
baseURL;
/**
* I18n locale if supported.
*
* Only platforms/methods that explicitly support i18n will use this, and the
* format requirements are up to the platform.
*/
locale;
constructor(options, defaultBaseURL, defaultLocale) {
const { headers } = options?.ofetchDefaults ?? {};
this.baseURL = options?.baseURL ?? defaultBaseURL;
this.ofetch = options?.ofetch ?? ofetch.create({
...options?.ofetchDefaults,
baseURL: this.baseURL,
headers: addHeaders(headers, [["user-agent", `UnOJ/${version}`]])
}, options?.ofetchCreateOptions);
this.locale = options?.locale ?? defaultLocale;
}
/**
* Fetch a problem from the platform.
* @param _id The problem ID.
* @returns The problem object.
*/
getProblem(_id) {
return Promise.reject(new UnsupportedError());
}
/**
* Fetch a contest from the platform.
* @param _id The contest ID.
* @returns The contest object.
*/
getContest(_id) {
return Promise.reject(new UnsupportedError());
}
};
/** An error that indicates a platform does not support a certain operation. */
var UnsupportedError = class extends UnOJError {
constructor() {
super("Unsupported operation");
}
};
/** An error that indicates a platform does not have a certain resource. */
var NotFoundError = class extends UnOJError {
constructor(thing) {
super(`Cannot find ${thing}`);
this.thing = thing;
}
};
var UnexpectedResponseError = class extends UnOJError {
constructor(data) {
super("Unexpected response, see the \"Compabtibility\" section of README.md of @un-oj/core (or un-oj) package.");
this.data = data;
}
};
//#endregion
export { NotFoundError, Platform, UnOJError, UnexpectedResponseError, UnsupportedError, addHeaders, getFirstKey, parseMemory, parseTime };