@blink-sdk/github
Version:
Blink SDK for GitHub tools.
1,354 lines (1,338 loc) • 247 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i$1 = 0, n = keys.length, key; i$1 < n; i$1++) {
key = keys[i$1];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
let node_crypto = require("node:crypto");
node_crypto = __toESM(node_crypto);
let __octokit_core = require("@octokit/core");
__octokit_core = __toESM(__octokit_core);
let ai = require("ai");
ai = __toESM(ai);
let module$1 = require("module");
module$1 = __toESM(module$1);
let zod = require("zod");
zod = __toESM(zod);
//#region ../../../node_modules/universal-user-agent/index.js
function getUserAgent() {
if (typeof navigator === "object" && "userAgent" in navigator) return navigator.userAgent;
if (typeof process === "object" && process.version !== void 0) return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`;
return "<environment undetectable>";
}
//#endregion
//#region ../../../node_modules/@octokit/endpoint/dist-bundle/index.js
var VERSION$5 = "0.0.0-development";
var userAgent = `octokit-endpoint.js/${VERSION$5} ${getUserAgent()}`;
var DEFAULTS = {
method: "GET",
baseUrl: "https://api.github.com",
headers: {
accept: "application/vnd.github.v3+json",
"user-agent": userAgent
},
mediaType: { format: "" }
};
function lowercaseKeys(object) {
if (!object) return {};
return Object.keys(object).reduce((newObj, key) => {
newObj[key.toLowerCase()] = object[key];
return newObj;
}, {});
}
function isPlainObject$1(value) {
if (typeof value !== "object" || value === null) return false;
if (Object.prototype.toString.call(value) !== "[object Object]") return false;
const proto = Object.getPrototypeOf(value);
if (proto === null) return true;
const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value);
}
function mergeDeep(defaults, options) {
const result = Object.assign({}, defaults);
Object.keys(options).forEach((key) => {
if (isPlainObject$1(options[key])) if (!(key in defaults)) Object.assign(result, { [key]: options[key] });
else result[key] = mergeDeep(defaults[key], options[key]);
else Object.assign(result, { [key]: options[key] });
});
return result;
}
function removeUndefinedProperties(obj) {
for (const key in obj) if (obj[key] === void 0) delete obj[key];
return obj;
}
function merge(defaults, route, options) {
if (typeof route === "string") {
let [method, url] = route.split(" ");
options = Object.assign(url ? {
method,
url
} : { url: method }, options);
} else options = Object.assign({}, route);
options.headers = lowercaseKeys(options.headers);
removeUndefinedProperties(options);
removeUndefinedProperties(options.headers);
const mergedOptions = mergeDeep(defaults || {}, options);
if (options.url === "/graphql") {
if (defaults && defaults.mediaType.previews?.length) mergedOptions.mediaType.previews = defaults.mediaType.previews.filter((preview) => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews);
mergedOptions.mediaType.previews = (mergedOptions.mediaType.previews || []).map((preview) => preview.replace(/-preview/, ""));
}
return mergedOptions;
}
function addQueryParameters(url, parameters) {
const separator = /\?/.test(url) ? "&" : "?";
const names = Object.keys(parameters);
if (names.length === 0) return url;
return url + separator + names.map((name) => {
if (name === "q") return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+");
return `${name}=${encodeURIComponent(parameters[name])}`;
}).join("&");
}
var urlVariableRegex = /\{[^{}}]+\}/g;
function removeNonChars(variableName) {
return variableName.replace(/(?:^\W+)|(?:(?<!\W)\W+$)/g, "").split(/,/);
}
function extractUrlVariableNames(url) {
const matches = url.match(urlVariableRegex);
if (!matches) return [];
return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);
}
function omit(object, keysToOmit) {
const result = { __proto__: null };
for (const key of Object.keys(object)) if (keysToOmit.indexOf(key) === -1) result[key] = object[key];
return result;
}
function encodeReserved(str) {
return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) {
if (!/%[0-9A-Fa-f]/.test(part)) part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]");
return part;
}).join("");
}
function encodeUnreserved(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
});
}
function encodeValue(operator, value, key) {
value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value);
if (key) return encodeUnreserved(key) + "=" + value;
else return value;
}
function isDefined(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
return operator === ";" || operator === "&" || operator === "?";
}
function getValues(context, operator, key, modifier) {
var value = context[key], result = [];
if (isDefined(value) && value !== "") if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") value = value.substring(0, parseInt(modifier, 10));
result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : ""));
} else if (modifier === "*") if (Array.isArray(value)) value.filter(isDefined).forEach(function(value2) {
result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : ""));
});
else Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) result.push(encodeValue(operator, value[k], k));
});
else {
const tmp = [];
if (Array.isArray(value)) value.filter(isDefined).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
else Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
});
if (isKeyOperator(operator)) result.push(encodeUnreserved(key) + "=" + tmp.join(","));
else if (tmp.length !== 0) result.push(tmp.join(","));
}
else if (operator === ";") {
if (isDefined(value)) result.push(encodeUnreserved(key));
} else if (value === "" && (operator === "&" || operator === "?")) result.push(encodeUnreserved(key) + "=");
else if (value === "") result.push("");
return result;
}
function parseUrl(template) {
return { expand: expand.bind(null, template) };
}
function expand(template, context) {
var operators = [
"+",
"#",
".",
"/",
";",
"?",
"&"
];
template = template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function(_, expression, literal) {
if (expression) {
let operator = "";
const values = [];
if (operators.indexOf(expression.charAt(0)) !== -1) {
operator = expression.charAt(0);
expression = expression.substr(1);
}
expression.split(/,/g).forEach(function(variable) {
var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
});
if (operator && operator !== "+") {
var separator = ",";
if (operator === "?") separator = "&";
else if (operator !== "#") separator = operator;
return (values.length !== 0 ? operator : "") + values.join(separator);
} else return values.join(",");
} else return encodeReserved(literal);
});
if (template === "/") return template;
else return template.replace(/\/$/, "");
}
function parse$2(options) {
let method = options.method.toUpperCase();
let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}");
let headers = Object.assign({}, options.headers);
let body;
let parameters = omit(options, [
"method",
"baseUrl",
"url",
"headers",
"request",
"mediaType"
]);
const urlVariableNames = extractUrlVariableNames(url);
url = parseUrl(url).expand(parameters);
if (!/^http/.test(url)) url = options.baseUrl + url;
const omittedParameters = Object.keys(options).filter((option) => urlVariableNames.includes(option)).concat("baseUrl");
const remainingParameters = omit(parameters, omittedParameters);
const isBinaryRequest = /application\/octet-stream/i.test(headers.accept);
if (!isBinaryRequest) {
if (options.mediaType.format) headers.accept = headers.accept.split(/,/).map((format) => format.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(",");
if (url.endsWith("/graphql")) {
if (options.mediaType.previews?.length) {
const previewsFromAcceptHeader = headers.accept.match(/(?<![\w-])[\w-]+(?=-preview)/g) || [];
headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map((preview) => {
const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json";
return `application/vnd.github.${preview}-preview${format}`;
}).join(",");
}
}
}
if (["GET", "HEAD"].includes(method)) url = addQueryParameters(url, remainingParameters);
else if ("data" in remainingParameters) body = remainingParameters.data;
else if (Object.keys(remainingParameters).length) body = remainingParameters;
if (!headers["content-type"] && typeof body !== "undefined") headers["content-type"] = "application/json; charset=utf-8";
if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") body = "";
return Object.assign({
method,
url,
headers
}, typeof body !== "undefined" ? { body } : null, options.request ? { request: options.request } : null);
}
function endpointWithDefaults(defaults, route, options) {
return parse$2(merge(defaults, route, options));
}
function withDefaults$1(oldDefaults, newDefaults) {
const DEFAULTS2 = merge(oldDefaults, newDefaults);
const endpoint2 = endpointWithDefaults.bind(null, DEFAULTS2);
return Object.assign(endpoint2, {
DEFAULTS: DEFAULTS2,
defaults: withDefaults$1.bind(null, DEFAULTS2),
merge: merge.bind(null, DEFAULTS2),
parse: parse$2
});
}
var endpoint = withDefaults$1(null, DEFAULTS);
//#endregion
//#region ../../../node_modules/fast-content-type-parse/index.js
var require_fast_content_type_parse = /* @__PURE__ */ __commonJS({ "../../../node_modules/fast-content-type-parse/index.js": ((exports, module) => {
const NullObject = function NullObject$1() {};
NullObject.prototype = Object.create(null);
/**
* RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1
*
* parameter = token "=" ( token / quoted-string )
* token = 1*tchar
* tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
* / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
* / DIGIT / ALPHA
* ; any VCHAR, except delimiters
* quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
* qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
* obs-text = %x80-FF
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
*/
const paramRE = /; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu;
/**
* RegExp to match quoted-pair in RFC 7230 sec 3.2.6
*
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
* obs-text = %x80-FF
*/
const quotedPairRE = /\\([\v\u0020-\u00ff])/gu;
/**
* RegExp to match type in RFC 7231 sec 3.1.1.1
*
* media-type = type "/" subtype
* type = token
* subtype = token
*/
const mediaTypeRE = /^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u;
const defaultContentType = {
type: "",
parameters: new NullObject()
};
Object.freeze(defaultContentType.parameters);
Object.freeze(defaultContentType);
/**
* Parse media type to object.
*
* @param {string|object} header
* @return {Object}
* @public
*/
function parse$1(header) {
if (typeof header !== "string") throw new TypeError("argument header is required and must be a string");
let index = header.indexOf(";");
const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
if (mediaTypeRE.test(type) === false) throw new TypeError("invalid media type");
const result = {
type: type.toLowerCase(),
parameters: new NullObject()
};
if (index === -1) return result;
let key;
let match;
let value;
paramRE.lastIndex = index;
while (match = paramRE.exec(header)) {
if (match.index !== index) throw new TypeError("invalid parameter format");
index += match[0].length;
key = match[1].toLowerCase();
value = match[2];
if (value[0] === "\"") {
value = value.slice(1, value.length - 1);
quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
}
result.parameters[key] = value;
}
if (index !== header.length) throw new TypeError("invalid parameter format");
return result;
}
function safeParse$1(header) {
if (typeof header !== "string") return defaultContentType;
let index = header.indexOf(";");
const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
if (mediaTypeRE.test(type) === false) return defaultContentType;
const result = {
type: type.toLowerCase(),
parameters: new NullObject()
};
if (index === -1) return result;
let key;
let match;
let value;
paramRE.lastIndex = index;
while (match = paramRE.exec(header)) {
if (match.index !== index) return defaultContentType;
index += match[0].length;
key = match[1].toLowerCase();
value = match[2];
if (value[0] === "\"") {
value = value.slice(1, value.length - 1);
quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
}
result.parameters[key] = value;
}
if (index !== header.length) return defaultContentType;
return result;
}
module.exports.default = {
parse: parse$1,
safeParse: safeParse$1
};
module.exports.parse = parse$1;
module.exports.safeParse = safeParse$1;
module.exports.defaultContentType = defaultContentType;
}) });
//#endregion
//#region ../../../node_modules/@octokit/request-error/dist-src/index.js
var import_fast_content_type_parse = /* @__PURE__ */ __toESM(require_fast_content_type_parse(), 1);
var RequestError = class extends Error {
name;
/**
* http status code
*/
status;
/**
* Request options that lead to the error.
*/
request;
/**
* Response object if a response was received
*/
response;
constructor(message, statusCode, options) {
super(message);
this.name = "HttpError";
this.status = Number.parseInt(statusCode);
if (Number.isNaN(this.status)) this.status = 0;
if ("response" in options) this.response = options.response;
const requestCopy = Object.assign({}, options.request);
if (options.request.headers.authorization) requestCopy.headers = Object.assign({}, options.request.headers, { authorization: options.request.headers.authorization.replace(/(?<! ) .*$/, " [REDACTED]") });
requestCopy.url = requestCopy.url.replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]").replace(/\baccess_token=\w+/g, "access_token=[REDACTED]");
this.request = requestCopy;
}
};
//#endregion
//#region ../../../node_modules/@octokit/request/dist-bundle/index.js
var VERSION$4 = "10.0.3";
var defaults_default = { headers: { "user-agent": `octokit-request.js/${VERSION$4} ${getUserAgent()}` } };
function isPlainObject(value) {
if (typeof value !== "object" || value === null) return false;
if (Object.prototype.toString.call(value) !== "[object Object]") return false;
const proto = Object.getPrototypeOf(value);
if (proto === null) return true;
const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value);
}
async function fetchWrapper(requestOptions) {
const fetch$1 = requestOptions.request?.fetch || globalThis.fetch;
if (!fetch$1) throw new Error("fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing");
const log$1 = requestOptions.request?.log || console;
const parseSuccessResponseBody = requestOptions.request?.parseSuccessResponseBody !== false;
const body = isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body;
const requestHeaders = Object.fromEntries(Object.entries(requestOptions.headers).map(([name, value]) => [name, String(value)]));
let fetchResponse;
try {
fetchResponse = await fetch$1(requestOptions.url, {
method: requestOptions.method,
body,
redirect: requestOptions.request?.redirect,
headers: requestHeaders,
signal: requestOptions.request?.signal,
...requestOptions.body && { duplex: "half" }
});
} catch (error) {
let message = "Unknown Error";
if (error instanceof Error) {
if (error.name === "AbortError") {
error.status = 500;
throw error;
}
message = error.message;
if (error.name === "TypeError" && "cause" in error) {
if (error.cause instanceof Error) message = error.cause.message;
else if (typeof error.cause === "string") message = error.cause;
}
}
const requestError = new RequestError(message, 500, { request: requestOptions });
requestError.cause = error;
throw requestError;
}
const status = fetchResponse.status;
const url = fetchResponse.url;
const responseHeaders = {};
for (const [key, value] of fetchResponse.headers) responseHeaders[key] = value;
const octokitResponse = {
url,
status,
headers: responseHeaders,
data: ""
};
if ("deprecation" in responseHeaders) {
const matches = responseHeaders.link && responseHeaders.link.match(/<([^<>]+)>; rel="deprecation"/);
const deprecationLink = matches && matches.pop();
log$1.warn(`[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${responseHeaders.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}`);
}
if (status === 204 || status === 205) return octokitResponse;
if (requestOptions.method === "HEAD") {
if (status < 400) return octokitResponse;
throw new RequestError(fetchResponse.statusText, status, {
response: octokitResponse,
request: requestOptions
});
}
if (status === 304) {
octokitResponse.data = await getResponseData(fetchResponse);
throw new RequestError("Not modified", status, {
response: octokitResponse,
request: requestOptions
});
}
if (status >= 400) {
octokitResponse.data = await getResponseData(fetchResponse);
throw new RequestError(toErrorMessage(octokitResponse.data), status, {
response: octokitResponse,
request: requestOptions
});
}
octokitResponse.data = parseSuccessResponseBody ? await getResponseData(fetchResponse) : fetchResponse.body;
return octokitResponse;
}
async function getResponseData(response) {
const contentType = response.headers.get("content-type");
if (!contentType) return response.text().catch(() => "");
const mimetype = (0, import_fast_content_type_parse.safeParse)(contentType);
if (isJSONResponse(mimetype)) {
let text = "";
try {
text = await response.text();
return JSON.parse(text);
} catch (err$1) {
return text;
}
} else if (mimetype.type.startsWith("text/") || mimetype.parameters.charset?.toLowerCase() === "utf-8") return response.text().catch(() => "");
else return response.arrayBuffer().catch(() => /* @__PURE__ */ new ArrayBuffer(0));
}
function isJSONResponse(mimetype) {
return mimetype.type === "application/json" || mimetype.type === "application/scim+json";
}
function toErrorMessage(data) {
if (typeof data === "string") return data;
if (data instanceof ArrayBuffer) return "Unknown error";
if ("message" in data) {
const suffix = "documentation_url" in data ? ` - ${data.documentation_url}` : "";
return Array.isArray(data.errors) ? `${data.message}: ${data.errors.map((v) => JSON.stringify(v)).join(", ")}${suffix}` : `${data.message}${suffix}`;
}
return `Unknown error: ${JSON.stringify(data)}`;
}
function withDefaults(oldEndpoint, newDefaults) {
const endpoint2 = oldEndpoint.defaults(newDefaults);
const newApi = function(route, parameters) {
const endpointOptions = endpoint2.merge(route, parameters);
if (!endpointOptions.request || !endpointOptions.request.hook) return fetchWrapper(endpoint2.parse(endpointOptions));
const request2 = (route2, parameters2) => {
return fetchWrapper(endpoint2.parse(endpoint2.merge(route2, parameters2)));
};
Object.assign(request2, {
endpoint: endpoint2,
defaults: withDefaults.bind(null, endpoint2)
});
return endpointOptions.request.hook(request2, endpointOptions);
};
return Object.assign(newApi, {
endpoint: endpoint2,
defaults: withDefaults.bind(null, endpoint2)
});
}
var request = withDefaults(endpoint, defaults_default);
//#endregion
//#region ../../../node_modules/@octokit/oauth-methods/dist-bundle/index.js
function requestToOAuthBaseUrl(request$1) {
const endpointDefaults = request$1.endpoint.DEFAULTS;
return /^https:\/\/(api\.)?github\.com$/.test(endpointDefaults.baseUrl) ? "https://github.com" : endpointDefaults.baseUrl.replace("/api/v3", "");
}
async function oauthRequest(request$1, route, parameters) {
const withOAuthParameters = {
baseUrl: requestToOAuthBaseUrl(request$1),
headers: { accept: "application/json" },
...parameters
};
const response = await request$1(route, withOAuthParameters);
if ("error" in response.data) {
const error = new RequestError(`${response.data.error_description} (${response.data.error}, ${response.data.error_uri})`, 400, { request: request$1.endpoint.merge(route, withOAuthParameters) });
error.response = response;
throw error;
}
return response;
}
async function exchangeWebFlowCode(options) {
const request$1 = options.request || request;
const response = await oauthRequest(request$1, "POST /login/oauth/access_token", {
client_id: options.clientId,
client_secret: options.clientSecret,
code: options.code,
redirect_uri: options.redirectUrl
});
const authentication = {
clientType: options.clientType,
clientId: options.clientId,
clientSecret: options.clientSecret,
token: response.data.access_token,
scopes: response.data.scope.split(/\s+/).filter(Boolean)
};
if (options.clientType === "github-app") {
if ("refresh_token" in response.data) {
const apiTimeInMs = new Date(response.headers.date).getTime();
authentication.refreshToken = response.data.refresh_token, authentication.expiresAt = toTimestamp(apiTimeInMs, response.data.expires_in), authentication.refreshTokenExpiresAt = toTimestamp(apiTimeInMs, response.data.refresh_token_expires_in);
}
delete authentication.scopes;
}
return {
...response,
authentication
};
}
function toTimestamp(apiTimeInMs, expirationInSeconds) {
return new Date(apiTimeInMs + expirationInSeconds * 1e3).toISOString();
}
async function createDeviceCode(options) {
const request$1 = options.request || request;
const parameters = { client_id: options.clientId };
if ("scopes" in options && Array.isArray(options.scopes)) parameters.scope = options.scopes.join(" ");
return oauthRequest(request$1, "POST /login/device/code", parameters);
}
async function exchangeDeviceCode(options) {
const request$1 = options.request || request;
const response = await oauthRequest(request$1, "POST /login/oauth/access_token", {
client_id: options.clientId,
device_code: options.code,
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
});
const authentication = {
clientType: options.clientType,
clientId: options.clientId,
token: response.data.access_token,
scopes: response.data.scope.split(/\s+/).filter(Boolean)
};
if ("clientSecret" in options) authentication.clientSecret = options.clientSecret;
if (options.clientType === "github-app") {
if ("refresh_token" in response.data) {
const apiTimeInMs = new Date(response.headers.date).getTime();
authentication.refreshToken = response.data.refresh_token, authentication.expiresAt = toTimestamp2(apiTimeInMs, response.data.expires_in), authentication.refreshTokenExpiresAt = toTimestamp2(apiTimeInMs, response.data.refresh_token_expires_in);
}
delete authentication.scopes;
}
return {
...response,
authentication
};
}
function toTimestamp2(apiTimeInMs, expirationInSeconds) {
return new Date(apiTimeInMs + expirationInSeconds * 1e3).toISOString();
}
async function checkToken(options) {
const request$1 = options.request || request;
const response = await request$1("POST /applications/{client_id}/token", {
headers: { authorization: `basic ${btoa(`${options.clientId}:${options.clientSecret}`)}` },
client_id: options.clientId,
access_token: options.token
});
const authentication = {
clientType: options.clientType,
clientId: options.clientId,
clientSecret: options.clientSecret,
token: options.token,
scopes: response.data.scopes
};
if (response.data.expires_at) authentication.expiresAt = response.data.expires_at;
if (options.clientType === "github-app") delete authentication.scopes;
return {
...response,
authentication
};
}
async function refreshToken(options) {
const request$1 = options.request || request;
const response = await oauthRequest(request$1, "POST /login/oauth/access_token", {
client_id: options.clientId,
client_secret: options.clientSecret,
grant_type: "refresh_token",
refresh_token: options.refreshToken
});
const apiTimeInMs = new Date(response.headers.date).getTime();
const authentication = {
clientType: "github-app",
clientId: options.clientId,
clientSecret: options.clientSecret,
token: response.data.access_token,
refreshToken: response.data.refresh_token,
expiresAt: toTimestamp3(apiTimeInMs, response.data.expires_in),
refreshTokenExpiresAt: toTimestamp3(apiTimeInMs, response.data.refresh_token_expires_in)
};
return {
...response,
authentication
};
}
function toTimestamp3(apiTimeInMs, expirationInSeconds) {
return new Date(apiTimeInMs + expirationInSeconds * 1e3).toISOString();
}
async function resetToken(options) {
const request$1 = options.request || request;
const auth$4 = btoa(`${options.clientId}:${options.clientSecret}`);
const response = await request$1("PATCH /applications/{client_id}/token", {
headers: { authorization: `basic ${auth$4}` },
client_id: options.clientId,
access_token: options.token
});
const authentication = {
clientType: options.clientType,
clientId: options.clientId,
clientSecret: options.clientSecret,
token: response.data.token,
scopes: response.data.scopes
};
if (response.data.expires_at) authentication.expiresAt = response.data.expires_at;
if (options.clientType === "github-app") delete authentication.scopes;
return {
...response,
authentication
};
}
async function deleteToken(options) {
const request$1 = options.request || request;
const auth$4 = btoa(`${options.clientId}:${options.clientSecret}`);
return request$1("DELETE /applications/{client_id}/token", {
headers: { authorization: `basic ${auth$4}` },
client_id: options.clientId,
access_token: options.token
});
}
async function deleteAuthorization(options) {
const request$1 = options.request || request;
const auth$4 = btoa(`${options.clientId}:${options.clientSecret}`);
return request$1("DELETE /applications/{client_id}/grant", {
headers: { authorization: `basic ${auth$4}` },
client_id: options.clientId,
access_token: options.token
});
}
//#endregion
//#region ../../../node_modules/@octokit/auth-oauth-device/dist-bundle/index.js
async function getOAuthAccessToken(state, options) {
const cachedAuthentication = getCachedAuthentication(state, options.auth);
if (cachedAuthentication) return cachedAuthentication;
const { data: verification } = await createDeviceCode({
clientType: state.clientType,
clientId: state.clientId,
request: options.request || state.request,
scopes: options.auth.scopes || state.scopes
});
await state.onVerification(verification);
const authentication = await waitForAccessToken(options.request || state.request, state.clientId, state.clientType, verification);
state.authentication = authentication;
return authentication;
}
function getCachedAuthentication(state, auth2) {
if (auth2.refresh === true) return false;
if (!state.authentication) return false;
if (state.clientType === "github-app") return state.authentication;
const authentication = state.authentication;
const newScope = ("scopes" in auth2 && auth2.scopes || state.scopes).join(" ");
const currentScope = authentication.scopes.join(" ");
return newScope === currentScope ? authentication : false;
}
async function wait(seconds) {
await new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
}
async function waitForAccessToken(request$1, clientId, clientType, verification) {
try {
const options = {
clientId,
request: request$1,
code: verification.device_code
};
const { authentication } = clientType === "oauth-app" ? await exchangeDeviceCode({
...options,
clientType: "oauth-app"
}) : await exchangeDeviceCode({
...options,
clientType: "github-app"
});
return {
type: "token",
tokenType: "oauth",
...authentication
};
} catch (error) {
if (!error.response) throw error;
const errorType = error.response.data.error;
if (errorType === "authorization_pending") {
await wait(verification.interval);
return waitForAccessToken(request$1, clientId, clientType, verification);
}
if (errorType === "slow_down") {
await wait(verification.interval + 7);
return waitForAccessToken(request$1, clientId, clientType, verification);
}
throw error;
}
}
async function auth$3(state, authOptions) {
return getOAuthAccessToken(state, { auth: authOptions });
}
async function hook$3(state, request$1, route, parameters) {
let endpoint$1 = request$1.endpoint.merge(route, parameters);
if (/\/login\/(oauth\/access_token|device\/code)$/.test(endpoint$1.url)) return request$1(endpoint$1);
const { token } = await getOAuthAccessToken(state, {
request: request$1,
auth: { type: "oauth" }
});
endpoint$1.headers.authorization = `token ${token}`;
return request$1(endpoint$1);
}
var VERSION$3 = "0.0.0-development";
function createOAuthDeviceAuth(options) {
const requestWithDefaults = options.request || request.defaults({ headers: { "user-agent": `octokit-auth-oauth-device.js/${VERSION$3} ${getUserAgent()}` } });
const { request: request$1 = requestWithDefaults,...otherOptions } = options;
const state = options.clientType === "github-app" ? {
...otherOptions,
clientType: "github-app",
request: request$1
} : {
...otherOptions,
clientType: "oauth-app",
request: request$1,
scopes: options.scopes || []
};
if (!options.clientId) throw new Error("[@octokit/auth-oauth-device] \"clientId\" option must be set (https://github.com/octokit/auth-oauth-device.js#usage)");
if (!options.onVerification) throw new Error("[@octokit/auth-oauth-device] \"onVerification\" option must be a function (https://github.com/octokit/auth-oauth-device.js#usage)");
return Object.assign(auth$3.bind(null, state), { hook: hook$3.bind(null, state) });
}
//#endregion
//#region ../../../node_modules/@octokit/auth-oauth-user/dist-bundle/index.js
var VERSION$2 = "0.0.0-development";
async function getAuthentication(state) {
if ("code" in state.strategyOptions) {
const { authentication } = await exchangeWebFlowCode({
clientId: state.clientId,
clientSecret: state.clientSecret,
clientType: state.clientType,
onTokenCreated: state.onTokenCreated,
...state.strategyOptions,
request: state.request
});
return {
type: "token",
tokenType: "oauth",
...authentication
};
}
if ("onVerification" in state.strategyOptions) {
const deviceAuth = createOAuthDeviceAuth({
clientType: state.clientType,
clientId: state.clientId,
onTokenCreated: state.onTokenCreated,
...state.strategyOptions,
request: state.request
});
const authentication = await deviceAuth({ type: "oauth" });
return {
clientSecret: state.clientSecret,
...authentication
};
}
if ("token" in state.strategyOptions) return {
type: "token",
tokenType: "oauth",
clientId: state.clientId,
clientSecret: state.clientSecret,
clientType: state.clientType,
onTokenCreated: state.onTokenCreated,
...state.strategyOptions
};
throw new Error("[@octokit/auth-oauth-user] Invalid strategy options");
}
async function auth$2(state, options = {}) {
if (!state.authentication) state.authentication = state.clientType === "oauth-app" ? await getAuthentication(state) : await getAuthentication(state);
if (state.authentication.invalid) throw new Error("[@octokit/auth-oauth-user] Token is invalid");
const currentAuthentication = state.authentication;
if ("expiresAt" in currentAuthentication) {
if (options.type === "refresh" || new Date(currentAuthentication.expiresAt) < /* @__PURE__ */ new Date()) {
const { authentication } = await refreshToken({
clientType: "github-app",
clientId: state.clientId,
clientSecret: state.clientSecret,
refreshToken: currentAuthentication.refreshToken,
request: state.request
});
state.authentication = {
tokenType: "oauth",
type: "token",
...authentication
};
}
}
if (options.type === "refresh") {
if (state.clientType === "oauth-app") throw new Error("[@octokit/auth-oauth-user] OAuth Apps do not support expiring tokens");
if (!currentAuthentication.hasOwnProperty("expiresAt")) throw new Error("[@octokit/auth-oauth-user] Refresh token missing");
await state.onTokenCreated?.(state.authentication, { type: options.type });
}
if (options.type === "check" || options.type === "reset") {
const method = options.type === "check" ? checkToken : resetToken;
try {
const { authentication } = await method({
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
token: state.authentication.token,
request: state.request
});
state.authentication = {
tokenType: "oauth",
type: "token",
...authentication
};
if (options.type === "reset") await state.onTokenCreated?.(state.authentication, { type: options.type });
return state.authentication;
} catch (error) {
if (error.status === 404) {
error.message = "[@octokit/auth-oauth-user] Token is invalid";
state.authentication.invalid = true;
}
throw error;
}
}
if (options.type === "delete" || options.type === "deleteAuthorization") {
const method = options.type === "delete" ? deleteToken : deleteAuthorization;
try {
await method({
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
token: state.authentication.token,
request: state.request
});
} catch (error) {
if (error.status !== 404) throw error;
}
state.authentication.invalid = true;
return state.authentication;
}
return state.authentication;
}
var ROUTES_REQUIRING_BASIC_AUTH = /\/applications\/[^/]+\/(token|grant)s?/;
function requiresBasicAuth(url) {
return url && ROUTES_REQUIRING_BASIC_AUTH.test(url);
}
async function hook$2(state, request$1, route, parameters = {}) {
const endpoint$1 = request$1.endpoint.merge(route, parameters);
if (/\/login\/(oauth\/access_token|device\/code)$/.test(endpoint$1.url)) return request$1(endpoint$1);
if (requiresBasicAuth(endpoint$1.url)) {
const credentials = btoa(`${state.clientId}:${state.clientSecret}`);
endpoint$1.headers.authorization = `basic ${credentials}`;
return request$1(endpoint$1);
}
const { token } = state.clientType === "oauth-app" ? await auth$2({
...state,
request: request$1
}) : await auth$2({
...state,
request: request$1
});
endpoint$1.headers.authorization = "token " + token;
return request$1(endpoint$1);
}
function createOAuthUserAuth({ clientId, clientSecret, clientType = "oauth-app", request: request$1 = request.defaults({ headers: { "user-agent": `octokit-auth-oauth-app.js/${VERSION$2} ${getUserAgent()}` } }), onTokenCreated,...strategyOptions }) {
const state = Object.assign({
clientType,
clientId,
clientSecret,
onTokenCreated,
strategyOptions,
request: request$1
});
return Object.assign(auth$2.bind(null, state), { hook: hook$2.bind(null, state) });
}
createOAuthUserAuth.VERSION = VERSION$2;
//#endregion
//#region ../../../node_modules/@octokit/auth-oauth-app/dist-bundle/index.js
async function auth$1(state, authOptions) {
if (authOptions.type === "oauth-app") return {
type: "oauth-app",
clientId: state.clientId,
clientSecret: state.clientSecret,
clientType: state.clientType,
headers: { authorization: `basic ${btoa(`${state.clientId}:${state.clientSecret}`)}` }
};
if ("factory" in authOptions) {
const { type,...options } = {
...authOptions,
...state
};
return authOptions.factory(options);
}
const common = {
clientId: state.clientId,
clientSecret: state.clientSecret,
request: state.request,
...authOptions
};
const userAuth = state.clientType === "oauth-app" ? await createOAuthUserAuth({
...common,
clientType: state.clientType
}) : await createOAuthUserAuth({
...common,
clientType: state.clientType
});
return userAuth();
}
async function hook$1(state, request2, route, parameters) {
let endpoint$1 = request2.endpoint.merge(route, parameters);
if (/\/login\/(oauth\/access_token|device\/code)$/.test(endpoint$1.url)) return request2(endpoint$1);
if (state.clientType === "github-app" && !requiresBasicAuth(endpoint$1.url)) throw new Error(`[@octokit/auth-oauth-app] GitHub Apps cannot use their client ID/secret for basic authentication for endpoints other than "/applications/{client_id}/**". "${endpoint$1.method} ${endpoint$1.url}" is not supported.`);
const credentials = btoa(`${state.clientId}:${state.clientSecret}`);
endpoint$1.headers.authorization = `basic ${credentials}`;
try {
return await request2(endpoint$1);
} catch (error) {
if (error.status !== 401) throw error;
error.message = `[@octokit/auth-oauth-app] "${endpoint$1.method} ${endpoint$1.url}" does not support clientId/clientSecret basic authentication.`;
throw error;
}
}
var VERSION$1 = "0.0.0-development";
function createOAuthAppAuth(options) {
const state = Object.assign({
request: request.defaults({ headers: { "user-agent": `octokit-auth-oauth-app.js/${VERSION$1} ${getUserAgent()}` } }),
clientType: "oauth-app"
}, options);
return Object.assign(auth$1.bind(null, state), { hook: hook$1.bind(null, state) });
}
//#endregion
//#region ../../../node_modules/universal-github-app-jwt/lib/utils.js
/**
* @param {string} privateKey
* @returns {boolean}
*/
function isPkcs1(privateKey) {
return privateKey.includes("-----BEGIN RSA PRIVATE KEY-----");
}
/**
* @param {string} privateKey
* @returns {boolean}
*/
function isOpenSsh(privateKey) {
return privateKey.includes("-----BEGIN OPENSSH PRIVATE KEY-----");
}
/**
* @param {string} str
* @returns {ArrayBuffer}
*/
function string2ArrayBuffer(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i$1 = 0, strLen = str.length; i$1 < strLen; i$1++) bufView[i$1] = str.charCodeAt(i$1);
return buf;
}
/**
* @param {string} pem
* @returns {ArrayBuffer}
*/
function getDERfromPEM(pem) {
const pemB64 = pem.trim().split("\n").slice(1, -1).join("");
const decoded = atob(pemB64);
return string2ArrayBuffer(decoded);
}
/**
* @param {import('../internals').Header} header
* @param {import('../internals').Payload} payload
* @returns {string}
*/
function getEncodedMessage(header, payload) {
return `${base64encodeJSON(header)}.${base64encodeJSON(payload)}`;
}
/**
* @param {ArrayBuffer} buffer
* @returns {string}
*/
function base64encode(buffer) {
var binary = "";
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i$1 = 0; i$1 < len; i$1++) binary += String.fromCharCode(bytes[i$1]);
return fromBase64(btoa(binary));
}
/**
* @param {string} base64
* @returns {string}
*/
function fromBase64(base64) {
return base64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
}
/**
* @param {Record<string,unknown>} obj
* @returns {string}
*/
function base64encodeJSON(obj) {
return fromBase64(btoa(JSON.stringify(obj)));
}
//#endregion
//#region ../../../node_modules/universal-github-app-jwt/lib/crypto-node.js
function convertPrivateKey(privateKey) {
if (!isPkcs1(privateKey)) return privateKey;
return (0, node_crypto.createPrivateKey)(privateKey).export({
type: "pkcs8",
format: "pem"
});
}
//#endregion
//#region ../../../node_modules/universal-github-app-jwt/lib/get-token.js
/**
* @param {import('../internals').GetTokenOptions} options
* @returns {Promise<string>}
*/
async function getToken({ privateKey, payload }) {
const convertedPrivateKey = convertPrivateKey(privateKey);
/* c8 ignore start */
if (isPkcs1(convertedPrivateKey)) throw new Error("[universal-github-app-jwt] Private Key is in PKCS#1 format, but only PKCS#8 is supported. See https://github.com/gr2m/universal-github-app-jwt#private-key-formats");
/* c8 ignore stop */
if (isOpenSsh(convertedPrivateKey)) throw new Error("[universal-github-app-jwt] Private Key is in OpenSSH format, but only PKCS#8 is supported. See https://github.com/gr2m/universal-github-app-jwt#private-key-formats");
const algorithm = {
name: "RSASSA-PKCS1-v1_5",
hash: { name: "SHA-256" }
};
/** @type {import('../internals').Header} */
const header = {
alg: "RS256",
typ: "JWT"
};
const privateKeyDER = getDERfromPEM(convertedPrivateKey);
const importedKey = await node_crypto.subtle.importKey("pkcs8", privateKeyDER, algorithm, false, ["sign"]);
const encodedMessage = getEncodedMessage(header, payload);
const encodedMessageArrBuf = string2ArrayBuffer(encodedMessage);
const signatureArrBuf = await node_crypto.subtle.sign(algorithm.name, importedKey, encodedMessageArrBuf);
const encodedSignature = base64encode(signatureArrBuf);
return `${encodedMessage}.${encodedSignature}`;
}
//#endregion
//#region ../../../node_modules/universal-github-app-jwt/index.js
/**
* @param {import(".").Options} options
* @returns {Promise<import(".").Result>}
*/
async function githubAppJwt({ id, privateKey, now = Math.floor(Date.now() / 1e3) }) {
const privateKeyWithNewlines = privateKey.replace(/\\n/g, "\n");
const nowWithSafetyMargin = now - 30;
const expiration = nowWithSafetyMargin + 600;
const payload = {
iat: nowWithSafetyMargin,
exp: expiration,
iss: id
};
const token = await getToken({
privateKey: privateKeyWithNewlines,
payload
});
return {
appId: id,
expiration,
token
};
}
//#endregion
//#region ../../../node_modules/toad-cache/dist/toad-cache.mjs
var LruObject = class {
constructor(max$1 = 1e3, ttlInMsecs = 0) {
if (isNaN(max$1) || max$1 < 0) throw new Error("Invalid max value");
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) throw new Error("Invalid ttl value");
this.first = null;
this.items = Object.create(null);
this.last = null;
this.size = 0;
this.max = max$1;
this.ttl = ttlInMsecs;
}
bumpLru(item) {
if (this.last === item) return;
const last = this.last;
const next = item.next;
const prev = item.prev;
if (this.first === item) this.first = next;
item.next = null;
item.prev = last;
last.next = item;
if (prev !== null) prev.next = next;
if (next !== null) next.prev = prev;
this.last = item;
}
clear() {
this.items = Object.create(null);
this.first = null;
this.last = null;
this.size = 0;
}
delete(key) {
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
const item = this.items[key];
delete this.items[key];
this.size--;
if (item.prev !== null) item.prev.next = item.next;
if (item.next !== null) item.next.prev = item.prev;
if (this.first === item) this.first = item.next;
if (this.last === item) this.last = item.prev;
}
}
deleteMany(keys) {
for (var i$1 = 0; i$1 < keys.length; i$1++) this.delete(keys[i$1]);
}
evict() {
if (this.size > 0) {
const item = this.first;
delete this.items[item.key];
if (--this.size === 0) {
this.first = null;
this.last = null;
} else {
this.first = item.next;
this.first.prev = null;
}
}
}
expiresAt(key) {
if (Object.prototype.hasOwnProperty.call(this.items, key)) return this.items[key].expiry;
}
get(key) {
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
const item = this.items[key];
if (this.ttl > 0 && item.expiry <= Date.now()) {
this.delete(key);
return;
}
this.bumpLru(item);
return item.value;
}
}
getMany(keys) {
const result = [];
for (var i$1 = 0; i$1 < keys.length; i$1++) result.push(this.get(keys[i$1]));
return result;
}
keys() {
return Object.keys(this.items);
}
set(key, value) {
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
const item$1 = this.items[key];
item$1.value = value;
item$1.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
if (this.last !== item$1) this.bumpLru(item$1);
return;
}
if (this.max > 0 && this.size === this.max) this.evict();
const item = {
expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
key,
prev: this.last,
next: null,
value
};
this.items[key] = item;
if (++this.size === 1) this.first = item;
else this.last.next = item;
this.last = item;
}
};
//#endregion
//#region ../../../node_modules/@octokit/auth-app/dist-node/index.js
async function getAppAuthentication({ appId, privateKey, timeDifference, createJwt }) {
try {
if (createJwt) {
const { jwt, expiresAt } = await createJwt(appId, timeDifference);
return {
type: "app",
token: jwt,
appId,
expiresAt
};
}
const authOptions = {
id: appId,
privateKey
};
if (timeDifference) Object.assign(authOptions, { now: Math.floor(Date.now() / 1e3) + timeDifference });
const appAuthentication = await githubAppJwt(authOptions);
return {
type: "app",
token: appAuthentication.token,
appId: appAuthentication.appId,
expiresAt: (/* @__PURE__ */ new Date(appAuthentication.expiration * 1e3)).toISOString()
};
} catch (error) {
if (privateKey === "-----BEGIN RSA PRIVATE KEY-----") throw new Error("The 'privateKey` option contains only the first line '-----BEGIN RSA PRIVATE KEY-----'. If you are setting it using a `.env` file, make sure it is set on a single line with newlines replaced by '\n'");
else throw error;
}
}
function getCache() {
return new LruObject(15e3, 1e3 * 60 * 59);
}
async function get(cache, options) {
const cacheKey = optionsToCacheKey(options);
const result = await cache.get(cacheKey);
if (!result) return;
const [token, createdAt, expiresAt, repositorySelection, permissionsString, singleFileName] = result.split("|");
const permissions = options.permissions || permissionsString.split(/,/).reduce((permissions2, string) => {
if (/!$/.test(string)) permissions2[string.slice(0, -1)] = "write";
else permissions2[string] = "read";
return permissions2;
}, {});
return {
token,
createdAt,
expiresAt,
permissions,
repositoryIds: options.repositoryIds,
repositoryNames: options.repositoryNames,
singleFileName,
repositorySelection
};
}
async function set(cache, options, data) {
const key = optionsToCacheKey(options);
const permissionsString = options.permissions ? "" : Object.keys(data.permissions).map((name) => `${name}${data.permissions[name] === "write" ? "!" : ""}`).join(",");
const value = [
data.token,
data.createdAt,
data.expiresAt,
data.repositorySelection,
permissionsString,
data.singleFileName
].join("|");
await cache.set(key, value);
}
function optionsToCacheKey({ installationId, permissions = {}, repositoryIds = [], repositoryNames = [] }) {
const permissionsString = Object.keys(permissions).sort().map((name) => permissions[name] === "read" ? name : `${name}!`).join(",");
const repositoryIdsString = repositoryIds.sort().join(",");
const repositoryNamesString = repositoryNames.join(",");
return [
installationId,
repositoryIdsString,
repositoryNamesString,
permissionsString
].filter(Boolean).join("|");
}
function toTokenAuthentication({ installationId, token, createdAt, expiresAt, repositorySelection, permissions, repositoryIds, repositoryNames, singleFileName }) {
return Object.assign({
type: "token",
tokenType: "installation",
token,
installationId,
permissions,
createdAt,
expiresAt,
repositorySelection
}, repositoryIds ? { repositoryIds } : null, repositoryNames ? { repositoryNames } : null, singleFileName ? { singleFileName } : null);
}
async function getInstallationAuthentication(state, options, customRequest) {
const installationId = Number(options.installationId || state.installationId);
if (!installationId) throw new Error("[@octokit/auth-app] installationId option is required for installation authentication.");
if (options.factory) {
const { type, factory, oauthApp,...factoryAuthOptions } = {
...stat