UNPKG

bbop-rest-manager

Version:

This is the 'new' version of the manager event model for BBOP systems.

271 lines (270 loc) 10.7 kB
//#region \0rolldown/runtime.js 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 __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; 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 bbop_core = require("bbop-core"); bbop_core = __toESM(bbop_core, 1); let underscore = require("underscore"); underscore = __toESM(underscore, 1); let bbop_registry = require("bbop-registry"); bbop_registry = __toESM(bbop_registry, 1); //#region src/manager.js /** * Generic BBOP manager for dealing with basic generic REST calls. * This specific one is designed to be overridden by its subclasses. * This one pretty much just uses its incoming resource string as the data. * Mostly for testing purposes. * * Both a <bbop-rest-response> (or clean error data) and the manager * itself (this as anchor) should be passed to the callbacks. * * @module bbop-rest-manager */ function warnDeprecated(message) { console.warn(message); } function normalizeHeaders(headerPairs) { return Object.fromEntries(headerPairs || []); } function methodWithDefault(method) { if (!method) return "GET"; return method.toUpperCase(); } function buildUrl(resource, payload, method) { if (method !== "GET" || underscore.default.isEmpty(payload)) return resource; var url = new URL(resource); var params = new URLSearchParams(url.search); Object.entries(payload).forEach(function([key, value]) { if (Array.isArray(value)) value.forEach(function(item) { params.append(key, item); }); else if (typeof value !== "undefined" && value !== null) params.append(key, value); }); url.search = params.toString(); return url.toString(); } function buildRequestInit(payload, method, headers) { var requestHeaders = normalizeHeaders(headers); var init = { method, headers: requestHeaders }; if (method === "GET") return init; if (!underscore.default.isEmpty(payload)) { var body = new URLSearchParams(); Object.entries(payload).forEach(function([key, value]) { if (Array.isArray(value)) value.forEach(function(item) { body.append(key, item); }); else if (typeof value !== "undefined" && value !== null) body.append(key, value); }); if (!Object.keys(requestHeaders).some(function(header) { return header.toLowerCase() === "content-type"; })) requestHeaders["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"; init.body = body; } return init; } function normalizeErrorMessage(error) { if (!error) return "unknown fetch error"; if (error instanceof Error) return error.message; return String(error); } /** * Constructor for the REST manager. * * See also: module:bbop-registry * * @constructor * @param {Object} response_handler - the response handler class to use for each call * @returns {Object} rest manager object */ function manager_base(response_handler) { bbop_registry.default.call(this, ["success", "error"]); this._is_a = "bbop-rest-manager.base"; var anchor = this; this._logger = new bbop_core.default.logger(this._is_a); this._logger.DEBUG = false; function ll(str) { anchor._logger.kvetch(str); } this._response_handler = response_handler; this._qurl = null; this._qpayload = {}; this._qmethod = "GET"; this._headers = []; this._safety = false; this.debug = function(p) { if (p === true || p === false) this._logger.DEBUG = p; return this._logger.DEBUG; }; this._ensure_arguments = function(url, payload, method, headers) { ll("ensure arguments..."); if (typeof url !== "undefined") this.resource(url); if (typeof payload !== "undefined") this.payload(payload); if (typeof method !== "undefined") this.method(method); if (typeof headers !== "undefined") this.headers(headers); if (!this.resource()) throw new Error("must have resource defined"); }; this._apply_callbacks_by_response = function(response) { ll("apply callbacks by response..."); if (response && response.okay()) anchor.apply_callbacks("success", [response, anchor]); else anchor.apply_callbacks("error", [response, anchor]); }; this.resource = function(in_url) { ll("resource called with: " + in_url); if (typeof in_url !== "undefined" && bbop_core.default.what_is(in_url) === "string") anchor._qurl = in_url; return anchor._qurl; }; this.payload = function(payload) { ll("payload called with: " + payload); if (bbop_core.default.is_defined(payload) && bbop_core.default.what_is(payload) === "object") anchor._qpayload = payload; return bbop_core.default.clone(anchor._qpayload); }; this.method = function(method) { ll("method called with: " + method); if (bbop_core.default.is_defined(method) && bbop_core.default.what_is(method) === "string") anchor._qmethod = methodWithDefault(method); return anchor._qmethod; }; this.headers = function(in_headers) { ll("headers called with: " + in_headers); if (in_headers && underscore.default.isArray(in_headers)) anchor._headers = in_headers; return anchor._headers; }; this.run_promise_functions = async function(promise_function_stack, accumulator_function, final_function, error_function) { var initialCount = promise_function_stack.length || 0; while (!underscore.default.isEmpty(promise_function_stack)) { var promise_runner = promise_function_stack.shift(); try { accumulator_function(await promise_runner(), anchor); } catch (err) { if (err) error_function(err, anchor); return initialCount; } } final_function(anchor); return initialCount; }; } bbop_core.default.extend(manager_base, bbop_registry.default); manager_base.prototype.fetch = function(url, payload, method, headers) { this._logger.kvetch("called fetch"); this._ensure_arguments(url, payload, method, headers); var response = new this._response_handler(this.payload()); response.okay(true); response.message("empty"); response.message_type("success"); this._apply_callbacks_by_response(response); return response; }; manager_base.prototype.start = function(url, payload, method, headers) { this._ensure_arguments(url, payload, method, headers); var response = new this._response_handler(this.payload()); response.okay(true); response.message("empty"); response.message_type("success"); this._apply_callbacks_by_response(response); return Promise.resolve(response); }; var manager_fetch = function(response_handler) { manager_base.call(this, response_handler); this._is_a = "bbop-rest-manager.fetch"; }; bbop_core.default.extend(manager_fetch, manager_base); manager_fetch.prototype.fetch = function(url, payload, method, headers) { this._logger.kvetch("called fetch"); this.start(url, payload, method, headers); return null; }; manager_fetch.prototype.start = async function(url, payload, method, headers) { var anchor = this; this._ensure_arguments(url, payload, method, headers); var requestMethod = methodWithDefault(anchor.method()); var requestUrl = buildUrl(anchor.resource(), anchor.payload(), requestMethod); var requestInit = buildRequestInit(anchor.payload(), requestMethod, anchor.headers()); try { var fetchResponse = await fetch(requestUrl, requestInit); var rawText = await fetchResponse.text(); var response = new anchor._response_handler(rawText); if (fetchResponse.ok && response && response.okay()) { anchor.apply_callbacks("success", [response, anchor]); return response; } if (!response) response = new anchor._response_handler(null); response.okay(false); response.message_type("error"); if (!rawText) response.message(`HTTP ${fetchResponse.status}`); else if (fetchResponse.ok) response.message("bad response"); else response.message(`HTTP ${fetchResponse.status}`); anchor.apply_callbacks("error", [response, anchor]); return response; } catch (error) { var errorResponse = new anchor._response_handler(null); errorResponse.okay(false); errorResponse.message(normalizeErrorMessage(error)); errorResponse.message_type("error"); anchor.apply_callbacks("error", [errorResponse, anchor]); return errorResponse; } }; var manager_node = function(response_handler) { manager_fetch.call(this, response_handler); this._is_a = "bbop-rest-manager.node"; }; bbop_core.default.extend(manager_node, manager_fetch); var manager_sync_request = function(response_handler) { manager_fetch.call(this, response_handler); this._is_a = "bbop-rest-manager.sync_request"; }; bbop_core.default.extend(manager_sync_request, manager_fetch); manager_sync_request.prototype.fetch = function(url, payload, method, headers) { warnDeprecated("bbop-rest-manager.sync_request is deprecated; requests are now asynchronous and fetch() returns null. Use start() instead."); this._logger.kvetch("called fetch"); manager_fetch.prototype.start.call(this, url, payload, method, headers); return null; }; manager_sync_request.prototype.start = function(url, payload, method, headers) { warnDeprecated("bbop-rest-manager.sync_request is deprecated; requests are now asynchronous. Use start() as a promise-based API."); return manager_fetch.prototype.start.call(this, url, payload, method, headers); }; var manager_jquery = function(response_handler) { manager_fetch.call(this, response_handler); this._is_a = "bbop-rest-manager.jquery"; this._use_jsonp = false; this._jsonp_callback = "json.wrf"; }; bbop_core.default.extend(manager_jquery, manager_fetch); manager_jquery.prototype.use_jsonp = function(use_p) { if (typeof use_p !== "undefined") warnDeprecated("bbop-rest-manager.jquery JSONP support has been removed; use_jsonp() is now a no-op."); return this._use_jsonp; }; manager_jquery.prototype.jsonp_callback = function(cstring) { if (typeof cstring !== "undefined") warnDeprecated("bbop-rest-manager.jquery JSONP support has been removed; jsonp_callback() is now a no-op."); return this._jsonp_callback; }; var manager_default = { base: manager_base, node: manager_node, sync_request: manager_sync_request, jquery: manager_jquery }; //#endregion module.exports = manager_default;