openblox
Version:
Roblox API Wrapper For Both Classic And OpenCloud APIs.
155 lines (154 loc) • 7.37 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var apiGroup_exports = {};
__export(apiGroup_exports, {
createApiGroup: () => createApiGroup
});
module.exports = __toCommonJS(apiGroup_exports);
var import_config = require("../../config");
var import_httpHandler = require("../../http/httpHandler");
var import_utils = require("../../utils/utils");
var import_http = require("../../http/http.utils");
var import_helpers = require("../../helpers");
const operationPrefixRegexWithVersion = /((?:.+)(?:v[1-9]+\/))(?:.+)/;
const operationPrefixRegexWithoutVersion = /(.+\/)(cloud\/)(?:v[1-9]+)(?:.+)/;
const getParams = (func) => {
let str = func.toString();
const argsStr = /(?:async) (?:\((?:\{ (.+) \})\))/.exec(str)?.[1];
if (!argsStr) return [];
return argsStr.replaceAll(/{(.*)}/g, "").replaceAll(/ = ([^,]+)/g, "").replaceAll(/:( *)/g, "").split(", ");
};
const formatSearchParams = (params) => {
if (typeof params == "string") return params;
if (!params) return "";
const [paramsKeys, paramsValues] = [Object.keys(params), Object.values(params)];
const formattedParams = {};
paramsValues.forEach((param, i) => {
if (param == void 0 || param == null) return;
if (typeof param == "string") return formattedParams[paramsKeys[i]] = param;
if (Array.isArray(param)) return formattedParams[paramsKeys[i]] = param.join(",");
if (param instanceof Date) return formattedParams[paramsKeys[i]] = param.toISOString();
return formattedParams[paramsKeys[i]] = param.toString();
});
return formattedParams;
};
const defaultGetCursors = (rawData) => {
return [rawData.previousPageCursor, rawData.nextPageCursor];
};
function isObjectEmpty(obj) {
for (var prop in obj) if (obj.hasOwnProperty(prop)) return false;
return true;
}
const isNoMoreData = (data) => {
if (data?.constructor == Object) return isObjectEmpty(data);
if (Array.isArray(data)) return !data.length;
return !!data;
};
const isCursorEmpty = (cursor) => !cursor || typeof cursor == "string" && cursor.length === 0;
const paginate = (initialResponse, callApiMethod, args, overrides, handlerFnCursorArg) => async function* () {
if (isNoMoreData(initialResponse.data)) return;
yield initialResponse;
let nextCursor = initialResponse.cursors?.next;
if (isCursorEmpty(nextCursor)) return;
while (true) {
const newValue = await callApiMethod.call(overrides, { ...args, [handlerFnCursorArg]: nextCursor });
if (isNoMoreData(newValue.data)) return;
yield newValue;
nextCursor = newValue.cursors?.next;
if (isCursorEmpty(nextCursor)) return;
}
};
const pollForResponse = async (url, operationPath, cloudKey) => {
const operationPrefix = operationPath.match(/^(\/?)cloud\/v[1-9]+(\/?)/) ? operationPrefixRegexWithoutVersion.exec(url)?.[1] : operationPrefixRegexWithVersion.exec(url)?.[1];
const operationUrl = `${operationPrefix}${operationPath}`;
const headers = { "x-api-key": cloudKey };
let response;
await (0, import_helpers.pollHttp)({ method: "GET", url: operationUrl, headers }, async (polledResponse, stopPolling) => {
if (!polledResponse.body.done) return;
response = polledResponse;
stopPolling();
});
return response;
};
const createApiGroup = ({ name: groupName, baseUrl, defaultGetCursors: groupDefaultGetCursors }) => ({
// createApiMethod.
createApiMethod: (handlerFn) => {
const handlerFnArgs = getParams(handlerFn);
const handlerFnCursorArg = handlerFnArgs.includes("cursor") ? "cursor" : handlerFnArgs.includes("startRowIndex") ? "startRowIndex" : handlerFnArgs.includes("pageNumber") ? "pageNumber" : null;
const thisDefaultGetCursors = groupDefaultGetCursors ?? defaultGetCursors;
const createCallApiMethod = (_baseUrl = baseUrl) => async function(args) {
const overrides = this;
const cookie = overrides?.cookie || import_config.config?.cookie;
const cloudKey = overrides?.cloudKey || import_config.config?.cloudKey;
const oauthToken = overrides?.oauthToken;
const handlerFnData = await handlerFn(args);
let { path, method, searchParams, applyFieldMask, body, formData, headers, getCursorsFn, pathToPoll, name } = handlerFnData;
const formatRawDataFn = handlerFnData.formatRawDataFn;
let formattedSearchParams = formatSearchParams(searchParams);
if (applyFieldMask && body && (0, import_utils.isObject)(body)) formattedSearchParams += `&updateMask=${(0, import_utils.objectToFieldMask)(body)}`;
const url = `${_baseUrl}${path}${formattedSearchParams ? `?${new URLSearchParams(formattedSearchParams).toString()}` : ""}`;
if (cookie || cloudKey || oauthToken) {
if (!headers) headers = {};
if (cookie) headers["Cookie"] = cookie;
if (cloudKey) headers["x-api-key"] = cloudKey;
if (oauthToken) headers["Authorization"] = `Bearer ${oauthToken}`;
}
let main;
main = async () => {
let response = await (0, import_httpHandler.HttpHandler)({ method, url, body, formData, headers });
if (!(response instanceof import_http.HttpResponse)) throw response;
let rawData = response.body;
let opPath = rawData?.path;
if (opPath && rawData?.done === false && (0, import_httpHandler.isOpenCloudUrl)(url)) {
console.warn(`Polling '${groupName}.${name}' (Please be patient)...`);
response = await pollForResponse(url, pathToPoll ? pathToPoll(rawData) : opPath, cloudKey);
rawData = response.body;
}
let apiMethodResult = formatRawDataFn ? { response, again: main, get data() {
return formatRawDataFn(rawData, response);
} } : { response, again: main, data: rawData };
if (handlerFnCursorArg) {
let [previousCursor, nextCursor] = (getCursorsFn ?? thisDefaultGetCursors)(rawData);
apiMethodResult.cursors = { previous: previousCursor, next: nextCursor };
if (args && !("__notRoot" in args)) {
apiMethodResult[Symbol.asyncIterator] = paginate(
apiMethodResult,
callApiMethod,
args,
overrides,
handlerFnCursorArg
);
}
}
return apiMethodResult;
};
return await main();
};
const callApiMethod = createCallApiMethod();
callApiMethod._deriveWithDifferentBaseUrl = (baseUrl2) => createCallApiMethod(baseUrl2);
return callApiMethod;
},
addExistingApiMethod: (method) => {
return method._deriveWithDifferentBaseUrl(baseUrl);
}
});
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
createApiGroup
});
;