UNPKG

ts-comply

Version:

TypeTools is a Typescript library for providing extensible tooling runtime validations and type helpers.

1,894 lines 96.4 kB
"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.push(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.push(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpCacheOp = exports.CacheEntry = exports.CacheDef = exports.CacheParser = exports.PostHandler = exports.PreHandler = exports.HttpOp = exports.HttpPathResolution = exports.HttpResponse = exports.HttpRequest = exports.HttpServerShim = exports.HTTP = exports.isClass = exports.HttpBaseLib = exports.HttpServerShimApi = exports.HttpApiOptions = exports.ReqProcessor = exports.HttpShimCode = void 0;
var express = __importStar(require("express"));
var config_util_1 = require("../../src/common/util/config.util");
var dev_null_proxy_1 = require("../../src/common/util/convenience/dev.null.proxy");
var secure_channel_1 = require("../secure-channel/secure-channel");
var http_models_1 = require("./http.models");
var http_shim_worker_security_1 = require("./http.shim.worker.security");
var defaultConfig = __importStar(require("./http.shim.default.config.json"));
var defaultGlobalConfig = __importStar(require("./http.shim.global.conf.json"));
var axios = __importStar(require("axios"));
var globals_ix_1 = require("../../src/common/globals.ix");
var secret_resolver_1 = require("../secret-resoluton/secret-resolver");
var destor_client_1 = require("./destor/destor.client");
var url = __importStar(require("url"));
var process_exit_handler_1 = require("../proc/process.exit.handler");
var HttpShimCodeEnum;
(function (HttpShimCodeEnum) {
    HttpShimCodeEnum[HttpShimCodeEnum["CACHE_DATA_FETCH_FAILED"] = 0] = "CACHE_DATA_FETCH_FAILED";
    HttpShimCodeEnum[HttpShimCodeEnum["ACCESSOR_HEADER_NOT_FOUND"] = 1] = "ACCESSOR_HEADER_NOT_FOUND";
    HttpShimCodeEnum[HttpShimCodeEnum["ACCESSOR_BAD_FORMAT"] = 2] = "ACCESSOR_BAD_FORMAT";
    HttpShimCodeEnum[HttpShimCodeEnum["NO_ACCESSOR"] = 3] = "NO_ACCESSOR";
    HttpShimCodeEnum[HttpShimCodeEnum["ENCRYPTED_OP_NO_SECURE_PAYLOAD"] = 4] = "ENCRYPTED_OP_NO_SECURE_PAYLOAD";
    HttpShimCodeEnum[HttpShimCodeEnum["ENCRYPTED_OP_PATH_NOT_FOUND"] = 5] = "ENCRYPTED_OP_PATH_NOT_FOUND";
    HttpShimCodeEnum[HttpShimCodeEnum["ENCRYPTED_OP_METHOD_NOT_FOUND"] = 6] = "ENCRYPTED_OP_METHOD_NOT_FOUND";
    HttpShimCodeEnum[HttpShimCodeEnum["ENCRYPTED_OP_NON_JSON_PAYLOAD"] = 7] = "ENCRYPTED_OP_NON_JSON_PAYLOAD";
    HttpShimCodeEnum[HttpShimCodeEnum["SECURE_CHANNEL_NOT_FOUND"] = 8] = "SECURE_CHANNEL_NOT_FOUND";
    HttpShimCodeEnum[HttpShimCodeEnum["AUTH_HEADER_NOT_FOUND"] = 9] = "AUTH_HEADER_NOT_FOUND";
    HttpShimCodeEnum[HttpShimCodeEnum["AUTH_HEADER_NOT_VALID"] = 10] = "AUTH_HEADER_NOT_VALID";
    HttpShimCodeEnum[HttpShimCodeEnum["AUTH_HEADER_SIGNED_BUT_PUBLIC_KEY_NOT_FOUND"] = 11] = "AUTH_HEADER_SIGNED_BUT_PUBLIC_KEY_NOT_FOUND";
    HttpShimCodeEnum[HttpShimCodeEnum["AUTH_HEADER_SIGNED_NO_ROLES_MAP"] = 12] = "AUTH_HEADER_SIGNED_NO_ROLES_MAP";
    HttpShimCodeEnum[HttpShimCodeEnum["AUTH_HEADER_SIGNED_ROLE_UNAUTHORZIED_FOR_API"] = 13] = "AUTH_HEADER_SIGNED_ROLE_UNAUTHORZIED_FOR_API";
    HttpShimCodeEnum[HttpShimCodeEnum["AUTH_HEADER_SIGNED_BUT_API_DENIES_ALL"] = 14] = "AUTH_HEADER_SIGNED_BUT_API_DENIES_ALL";
})(HttpShimCodeEnum || (HttpShimCodeEnum = {}));
exports.HttpShimCode = (0, globals_ix_1.ReturnCodeFamily)('HttpShimCode', HttpShimCodeEnum);
var ReqProcessor;
(function (ReqProcessor) {
    ReqProcessor["AUTH"] = "AUTH";
    ReqProcessor["BASIC"] = "BASIC";
    ReqProcessor["DECRYPT"] = "DECRYPT";
    ReqProcessor["ENCRYPT"] = "ENCRYPT";
})(ReqProcessor = exports.ReqProcessor || (exports.ReqProcessor = {}));
var HttpApiOptions = (function () {
    function HttpApiOptions() {
    }
    return HttpApiOptions;
}());
exports.HttpApiOptions = HttpApiOptions;
var HttpServerShimApi = (function (_super) {
    __extends(HttpServerShimApi, _super);
    function HttpServerShimApi() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.path = '';
        _this.fullpath = '';
        _this.method = http_models_1.HttpMethod.GET;
        return _this;
    }
    return HttpServerShimApi;
}(HttpApiOptions));
exports.HttpServerShimApi = HttpServerShimApi;
var HttpBaseLib;
(function (HttpBaseLib) {
    HttpBaseLib["EXPRESS"] = "EXPRESS";
})(HttpBaseLib = exports.HttpBaseLib || (exports.HttpBaseLib = {}));
function isClass(target) {
    return !!target.prototype && !!target.constructor.name;
}
exports.isClass = isClass;
function methodsRegister(httpMethods, path, apiOptions) {
    path = path.replace(/\/\//g, '/');
    return function (method, deco) {
        deco.addInitializer(function () {
            var target = this;
            var sourceClass = this.constructor;
            for (var _i = 0, httpMethods_1 = httpMethods; _i < httpMethods_1.length; _i++) {
                var httpMethod = httpMethods_1[_i];
                var apiKey = "".concat(httpMethod, " ").concat(path);
                var methodApi = {
                    class: sourceClass,
                    className: sourceClass.name,
                    method: httpMethod,
                    path: path,
                    handlerName: deco.name,
                };
                if (apiOptions) {
                    Object.assign(methodApi, apiOptions);
                }
                if (!target.apiMap) {
                    target.apiMap = {};
                }
                target.apiMap[apiKey] = methodApi;
                if (!target.apiRegistrations) {
                    target.apiRegistrations = [];
                }
                target.addRegistration(methodApi);
            }
        });
        return method;
    };
}
var HTTP = exports.HTTP = (function () {
    function HTTP() {
    }
    var _a;
    _a = HTTP;
    HTTP.GET = (function (path, apiOptions) {
        return methodsRegister([http_models_1.HttpMethod.GET], path, apiOptions);
    });
    HTTP.POST = (function (path, apiOptions) {
        return methodsRegister([http_models_1.HttpMethod.POST], path, apiOptions);
    });
    HTTP.PATCH = (function (path, apiOptions) {
        return methodsRegister([http_models_1.HttpMethod.PATCH], path, apiOptions);
    });
    HTTP.DELETE = (function (path, apiOptions) {
        return methodsRegister([http_models_1.HttpMethod.DELETE], path, apiOptions);
    });
    HTTP.METHODS = (function (methods, path, apiOptions) {
        return methodsRegister(methods, path, apiOptions);
    });
    HTTP.ACCESS = function (access) {
        return function (method, deco) {
            deco.addInitializer(function () {
                var target = this;
                if (typeof access === 'string') {
                    var strAccess = access;
                    access = {};
                    Object.defineProperty(access, strAccess, { value: true });
                }
                if (!access.class) {
                    Object.defineProperty(access, 'class', { value: target.constructor });
                }
                target.addAccessRule(deco.name, access);
            });
            return method;
        };
    };
    HTTP.ACL = _a.ACCESS;
    HTTP.SHIM = {
        ROOT_API_PROXY_REQUEST: '/proxy-request',
        ROOT_API_PUBLIC_INFO: '/public-info',
        ROOT_API_NEW_CHANNEL: '/secure-channel',
        ROOT_API_SECURE_API: '/secure-api',
    };
    HTTP.STATUS = http_models_1.HttpCode;
    return HTTP;
}());
;
var HttpServerShim = exports.HttpServerShim = function () {
    var _b;
    var _instanceExtraInitializers = [];
    var _getRoles_decorators;
    var _getServerPublicInfo_decorators;
    var _newSecureChannel_decorators;
    var _encryptedOperation_decorators;
    var _proxyRequestOperation_decorators;
    return _b = (function () {
            function HttpServerShim(config, globalConf, beforeSuper) {
                var _this = this;
                this.config = (__runInitializers(this, _instanceExtraInitializers), void 0);
                this.publicInfo = {};
                this.publicInfoString = '';
                this.authServers = {};
                this.apiPath = 'api';
                this.apiVersion = 'v1';
                this.apiPathList = [];
                this.apiPathIface = {};
                this.pathTree = {};
                this.defaultProcessors = [];
                this.proxyRequest = {
                    enabled: false,
                    requestCheckers: [],
                };
                this.secureChannels = {};
                this.workerFleet = {};
                this.cacheData = {};
                this.state = {
                    activePort: 0,
                    closed: false,
                    started: false,
                    apiRegistered: false,
                    apiRegisterStack: null,
                    closingPromise: null,
                };
                this.baseLibData = {
                    express: {
                        server: null,
                    },
                };
                if (beforeSuper) {
                    beforeSuper();
                }
                this.configGlobal = (0, config_util_1.completeConfig)(globalConf ? globalConf : {}, defaultGlobalConfig);
                this.config = this.normalizeServerConfig(config);
                this.preHandler = new PreHandler();
                this.postHandler = new PostHandler();
                this.configResolutionPromise = this.configResolution();
                this.setBaseLayer();
                if (!this.config.name) {
                    this.config.name = 'unnamed-server';
                }
                if (!this.config.env) {
                    this.config.env = 'test';
                }
                process_exit_handler_1.ProcessExit.addHandler(function (e) {
                    _this.close();
                });
            }
            HttpServerShim.prototype.configResolution = function () {
                return __awaiter(this, void 0, void 0, function () {
                    var destor, _a, _b, channelKey, i;
                    return __generator(this, function (_c) {
                        switch (_c.label) {
                            case 0:
                                if (!!this.config.skipConfigSecretResolution) return [3, 4];
                                return [4, this.getDestorClient()];
                            case 1:
                                destor = _c.sent();
                                _a = this;
                                return [4, secret_resolver_1.SecretManager.resolve(this.config, destor)];
                            case 2:
                                _a.config = _c.sent();
                                if (!!this.config.skipAuthServerResolution) return [3, 4];
                                _b = this;
                                return [4, secret_resolver_1.SecretManager.resolve('<config.authServers>', destor)];
                            case 3:
                                _b.authServers = (_c.sent());
                                _c.label = 4;
                            case 4:
                                if (this.config.security.secureChannel.enabled && this.config.security.secureChannel.signingKey) {
                                    channelKey = this.config.security.secureChannel.signingKey;
                                    if (!this.config.security.secureChannel.publicKey && channelKey && !channelKey.startsWith('<')) {
                                        this.config.security.secureChannel.publicKey = secure_channel_1.SecureHandshake.getPublicKeyFrom(channelKey);
                                    }
                                    for (i = 0; i < this.config.workers.secureChannelWorkers.initialCount; ++i) {
                                        this.addWorker(http_shim_worker_security_1.SecureChannelWorkerClient, {
                                            workerId: i, scopeName: this.config.scopeName, signingKey: channelKey,
                                        });
                                    }
                                }
                                this.configResolutionPromise = null;
                                this.afterConfigResolution();
                                return [2];
                        }
                    });
                });
            };
            HttpServerShim.prototype.registerApis = function () {
                if (this.state.apiRegistered) {
                    throw new Error("Cannot register apis twice; already registered from ".concat(this.state.apiRegisterStack));
                }
                this.state.apiRegistered = true;
                this.state.apiRegisterStack = new Error().stack;
                for (var _i = 0, _a = this.apiRegistrations; _i < _a.length; _i++) {
                    var api = _a[_i];
                    if (this instanceof api.class) {
                        this.register(api);
                    }
                }
            };
            HttpServerShim.prototype.normalizeServerConfig = function (config) {
                if (!config.scopeName) {
                    config.scopeName = "httpshim;pid=".concat(process.pid);
                }
                var newConfig = (0, config_util_1.completeConfig)(config, defaultConfig);
                newConfig.debug.showErrorStack = true;
                return newConfig;
            };
            HttpServerShim.prototype.addDefaultProcessor = function () {
                var processors = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    processors[_i] = arguments[_i];
                }
                if (this.state.apiRegistered) {
                    throw new Error("addDefaultProcessor must be called before api registration");
                }
                for (var _a = 0, processors_1 = processors; _a < processors_1.length; _a++) {
                    var proc = processors_1[_a];
                    this.defaultProcessors.push(proc);
                }
            };
            HttpServerShim.prototype.cacheDefine = function (init) {
                if (this.cacheData[init.path]) {
                    throw new Error("Cache path '".concat(init.path, "' is already defined."));
                }
                var def = new CacheDef(init);
                this.cacheData[def.path] = new CacheEntry({
                    value: null,
                    hits: 0,
                    version: 0,
                    def: def,
                });
                return def;
            };
            HttpServerShim.prototype.addWorker = function (workerClass, workerData) {
                if (!workerData) {
                    workerData = {};
                }
                if (!this.workerFleet[workerClass.name]) {
                    this.workerFleet[workerClass.name] = { workers: [] };
                }
                var workersReg = this.workerFleet[workerClass.name];
                var worker = new workerClass(workerData);
                workersReg.workers.push(worker);
                return worker;
            };
            HttpServerShim.prototype.pickWorker = function (workerClass) {
                if (!this.workerFleet[workerClass.name]) {
                    return dev_null_proxy_1.proxyParameterFunctionToNull;
                }
                var workers = this.workerFleet[workerClass.name].workers;
                if (workers.length === 0) {
                    return dev_null_proxy_1.proxyParameterFunctionToNull;
                }
                return this.workerFleet[workerClass.name].workers[0];
            };
            HttpServerShim.prototype.setBaseLayer = function () {
                switch (this.config.type) {
                    case HttpBaseLib.EXPRESS:
                        this.baseApp = express.default();
                        var secOptions_1 = this.configGlobal.http.securityHeaders;
                        if (secOptions_1.profile === 'allow-all') {
                            this.baseApp.use(function (req, res, next) {
                                if (secOptions_1.allowRequestOrigin) {
                                    res.header('Access-Control-Allow-Origin', secOptions_1.allowRequestOrigin);
                                }
                                if (secOptions_1.allowRequestHeaders) {
                                    res.header('Access-Control-Allow-Headers', secOptions_1.allowRequestOrigin);
                                }
                                if (req.method === 'OPTIONS') {
                                    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
                                    return res.end();
                                }
                                next();
                            });
                        }
                        break;
                }
            };
            HttpServerShim.prototype.setFinalLayer = function () {
                switch (this.config.type) {
                    case HttpBaseLib.EXPRESS:
                        break;
                }
            };
            HttpServerShim.prototype.getDestorClient = function () {
                return __awaiter(this, void 0, void 0, function () {
                    var _a;
                    return __generator(this, function (_b) {
                        switch (_b.label) {
                            case 0:
                                if (this.destor) {
                                    return [2, this.destor];
                                }
                                if (!this.destorPromise) return [3, 2];
                                return [4, this.destorPromise];
                            case 1: return [2, _b.sent()];
                            case 2:
                                this.destorPromise = (0, destor_client_1.getDestorClient)();
                                _a = this;
                                return [4, this.destorPromise];
                            case 3:
                                _a.destor = _b.sent();
                                return [2];
                        }
                    });
                });
            };
            HttpServerShim.prototype.getRoles = function (op) {
                return __awaiter(this, void 0, void 0, function () {
                    return __generator(this, function (_a) {
                        return [2, op.res.returnJsonPreserialized('')];
                    });
                });
            };
            HttpServerShim.prototype.getServerPublicInfo = function (op) {
                return __awaiter(this, void 0, void 0, function () {
                    return __generator(this, function (_a) {
                        return [2, op.res.returnJsonPreserialized(this.publicInfoString)];
                    });
                });
            };
            HttpServerShim.prototype.newSecureChannel = function (op) {
                return __awaiter(this, void 0, void 0, function () {
                    var accessInfoResult, accessInfo, peerInfo, channel, secureChannelResponseResult;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                accessInfoResult = this.checkAccessor(op, true);
                                if (accessInfoResult.bad) {
                                    return [2, op.raise(accessInfoResult, HTTP.STATUS.BAD_REQUEST)];
                                }
                                accessInfo = accessInfoResult.data;
                                peerInfo = {
                                    ecdhPublicKey: Buffer.from(accessInfo.channelPublicKey, 'base64'),
                                    iden: null, data: null,
                                };
                                return [4, this.pickWorker(http_shim_worker_security_1.SecureChannelWorkerClient).newChannel(peerInfo)];
                            case 1:
                                channel = _a.sent();
                                channel.signing = {
                                    type: '4Q',
                                    public: this.config.security.secureChannel.publicKey,
                                    private: this.config.security.secureChannel.signingKey,
                                };
                                this.secureChannels[channel.peerInfo.ecdhPublicKey.toString('base64')] = channel;
                                secureChannelResponseResult = channel.getSecureChannelResponse();
                                if (secureChannelResponseResult.bad) {
                                    return [2, op.raise(secureChannelResponseResult, HTTP.STATUS.UNAUTHORIZED)];
                                }
                                return [2, op.res.returnJson(secureChannelResponseResult.data)];
                        }
                    });
                });
            };
            HttpServerShim.prototype.encryptedOperation = function (op, skipRunning) {
                if (skipRunning === void 0) { skipRunning = false; }
                return __awaiter(this, void 0, void 0, function () {
                    var api;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                api = op.req.decryptedApiTarget;
                                if (!!skipRunning) return [3, 2];
                                return [4, this[api.handlerName](op)];
                            case 1:
                                _a.sent();
                                _a.label = 2;
                            case 2: return [2];
                        }
                    });
                });
            };
            HttpServerShim.prototype.proxyRequestOperation = function (op) {
                var _a;
                return __awaiter(this, void 0, void 0, function () {
                    var _i, _b, checker, allowed, message, paramsCopy, url, method, timeout, headers, newHeaders, _c, _d, headerName, headerValue, reqOpts, proxyRequestFunction;
                    var _e;
                    return __generator(this, function (_f) {
                        switch (_f.label) {
                            case 0:
                                if (this.proxyRequest.enabled) {
                                    return [2, op.res.returnNotOk(500, "Proxy request not enabled")];
                                }
                                if (!((_a = this.proxyRequest.requestCheckers) === null || _a === void 0 ? void 0 : _a.length)) return [3, 4];
                                _i = 0, _b = this.proxyRequest.requestCheckers;
                                _f.label = 1;
                            case 1:
                                if (!(_i < _b.length)) return [3, 4];
                                checker = _b[_i];
                                return [4, checker(op.req.params)];
                            case 2:
                                allowed = (_e = _f.sent(), _e.allowed), message = _e.message;
                                if (!allowed) {
                                    return [2, op.res.returnNotOk(500, "Proxy request not allowed: ".concat(message))];
                                }
                                _f.label = 3;
                            case 3:
                                _i++;
                                return [3, 1];
                            case 4:
                                paramsCopy = JSON.parse(JSON.stringify(op.req.params));
                                url = paramsCopy.__url;
                                method = paramsCopy.__method ? paramsCopy.__method : http_models_1.HttpMethod.GET;
                                timeout = paramsCopy.__timeout ? paramsCopy.__timeout : 7000;
                                headers = paramsCopy.__headers ? paramsCopy.__headers : '';
                                if (paramsCopy.__url) {
                                    delete paramsCopy.__url;
                                }
                                if (paramsCopy.__method) {
                                    delete paramsCopy.__method;
                                }
                                if (paramsCopy.__headers) {
                                    delete paramsCopy.__headers;
                                }
                                if (paramsCopy.__timeout) {
                                    delete paramsCopy.__timeout;
                                }
                                if (paramsCopy.__enc) {
                                    delete paramsCopy.__enc;
                                }
                                newHeaders = {};
                                for (_c = 0, _d = headers.split(','); _c < _d.length; _c++) {
                                    headerName = _d[_c];
                                    headerValue = op.req.getHeader(headerName);
                                    if (headerValue) {
                                        newHeaders[headerName] = headerValue;
                                    }
                                }
                                reqOpts = { timeout: timeout, headers: newHeaders, params: paramsCopy, };
                                switch (method) {
                                    case 'GET': {
                                        proxyRequestFunction = axios.default.get;
                                        break;
                                    }
                                    case 'PUT': {
                                        proxyRequestFunction = axios.default.put;
                                        break;
                                    }
                                    case 'POST': {
                                        proxyRequestFunction = axios.default.post;
                                        break;
                                    }
                                    case 'PATCH': {
                                        proxyRequestFunction = axios.default.patch;
                                        break;
                                    }
                                    case 'DELETE': {
                                        proxyRequestFunction = axios.default.delete;
                                        break;
                                    }
                                }
                                op.waitFor(function (resolve) {
                                    proxyRequestFunction.apply(axios.default, [url, reqOpts]).then(function (res) {
                                        if (typeof res.data === 'string') {
                                            op.res.returnJson({ message: res.data });
                                        }
                                        else {
                                            op.res.returnJson(res.data);
                                        }
                                        resolve();
                                    }).catch(function (e) {
                                        var res = e.response;
                                        if (res) {
                                            op.res.returnNotOk(res.status, "Proxy request failed: ".concat(res.data));
                                        }
                                        else {
                                            op.res.returnNotOk(500, "Proxy request failed: ".concat(e.message));
                                        }
                                        resolve();
                                    });
                                });
                                return [2];
                        }
                    });
                });
            };
            HttpServerShim.prototype.addAccessRule = function (memberMethodName, access) {
                if (!this.apiAccess) {
                    this.apiAccess = {};
                }
                var memberMethodName2 = memberMethodName;
                if (!this[memberMethodName2]) {
                    throw new Error("Cannot defined roles for non-existing class method '".concat(memberMethodName2, "'"));
                }
                this.apiAccess[memberMethodName2] = access;
            };
            HttpServerShim.prototype.addRegistration = function (api) {
                if (!this.apiRegistrations) {
                    this.apiRegistrations = [];
                }
                this.apiRegistrations.push(api);
            };
            HttpServerShim.prototype.register = function (api) {
                var _this = this;
                var apiVersion = api.apiVersion ? api.apiVersion : this.apiVersion;
                var apiPath = api.apiPath ? api.apiPath : this.apiPath;
                var finalMountPath = api.rootMount ? '' : "/".concat(apiPath, "/").concat(apiVersion);
                var fullpath = "".concat(finalMountPath, "/").concat(api.path).replace(/\/\//g, '/');
                api.fullpath = fullpath;
                this.pathResolve(fullpath, api);
                var apiKey = "".concat(api.method, " ").concat(api.fullpath);
                this.apiPathList.push(apiKey);
                var iface = this[api.handlerName + '_iface'];
                if (iface) {
                    iface.consumed = 1;
                    this.apiPathIface[apiKey] = {
                        method: api.method,
                        path: api.path,
                        handlerName: api.handlerName,
                        description: iface.description ? iface.description : '',
                        params: Object.keys(iface.params).map(function (paramName) {
                            var paramInfo = iface.params[paramName];
                            return {
                                required: paramInfo.required ? true : false, type: paramInfo.type
                            };
                        }),
                        returns: iface.returns.type,
                        acl: null,
                    };
                    setImmediate(function () {
                        _this.apiPathIface[apiKey].acl = _this.apiAccess[api.handlerName] ? _this.apiAccess[api.handlerName] : null;
                    });
                }
                if (!api.pre) {
                    api.pre = [];
                }
                if (!api.preDefaultProcesserAdded) {
                    api.pre = __spreadArray(__spreadArray([], this.defaultProcessors, true), api.pre, true);
                    api.pre = api.pre.filter(function (a, i) { return api.pre.indexOf(a) === i; });
                    api.preDefaultProcesserAdded = true;
                }
                switch (this.config.type) {
                    case HttpBaseLib.EXPRESS:
                        switch (api.method) {
                            case http_models_1.HttpMethod.GET: return this.baseApp.get(fullpath, expressHandler(this, api));
                            case http_models_1.HttpMethod.POST: return this.baseApp.post(fullpath, expressHandler(this, api));
                            case http_models_1.HttpMethod.PUT: return this.baseApp.put(fullpath, expressHandler(this, api));
                            case http_models_1.HttpMethod.PATCH: return this.baseApp.patch(fullpath, expressHandler(this, api));
                            case http_models_1.HttpMethod.DELETE: return this.baseApp.delete(fullpath, expressHandler(this, api));
                        }
                        break;
                }
                console.error("unmatched api", api);
            };
            HttpServerShim.prototype.beforeStart = function () { };
            HttpServerShim.prototype.afterStart = function () { };
            HttpServerShim.prototype.afterConfigResolution = function () { };
            HttpServerShim.prototype.beforeStop = function () { };
            HttpServerShim.prototype.afterStop = function () { };
            HttpServerShim.prototype.addPublicInfo = function (info) {
                Object.assign(this.publicInfo, info);
            };
            HttpServerShim.prototype.start = function (options) {
                var _this = this;
                return (0, globals_ix_1.promise)(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
                    var newAccess, app;
                    var _this = this;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (this.state.started) {
                                    return [2, resolve()];
                                }
                                this.state.started = true;
                                if (!this.configResolutionPromise) return [3, 2];
                                return [4, this.configResolutionPromise];
                            case 1:
                                _a.sent();
                                _a.label = 2;
                            case 2:
                                if (!options) {
                                    options = this.config.startOptions;
                                }
                                if (!options) {
                                    return [2, reject(new Error("Cannot start server without start options."))];
                                }
                                this.addPublicInfo({
                                    tokenRequired: this.config.security.token.required,
                                    accessorRequired: this.config.security.accessor.required,
                                    secureChannelScheme: this.config.security.secureChannel.encryption,
                                    secureChannelPublicKey: this.config.security.secureChannel.publicKey,
                                    secureChannelStrict: this.config.security.secureChannel.strict,
                                    secureChannelRequired: this.config.security.secureChannel.required,
                                    apiPathList: this.apiPathList,
                                    apiInterface: this.apiPathIface
                                });
                                this.apiRegistrations = this.apiRegistrations.filter(function (api) { return _this instanceof api.class; });
                                newAccess = {};
                                Object.keys(this.apiAccess).forEach(function (handlerName) {
                                    if (_this instanceof _this.apiAccess[handlerName]['class']) {
                                        newAccess[handlerName] = _this.apiAccess[handlerName];
                                    }
                                });
                                this.apiAccess = newAccess;
                                this.registerApis();
                                this.publicInfoString = JSON.stringify(this.publicInfo, null, 4);
                                switch (this.config.type) {
                                    case HttpBaseLib.EXPRESS:
                                        try {
                                            this.beforeStart();
                                        }
                                        catch (e) {
                                            console.error(e);
                                        }
                                        try {
                                            app = this.baseApp;
                                            this.baseLibData.express.server = app.listen(options.port, function () {
                                                _this.state.activePort = options.port;
                                                resolve();
                                                try {
                                                    _this.afterStart();
                                                }
                                                catch (e) {
                                                    console.error(e);
                                                }
                                            });
                                        }
                                        catch (e) {
                                            return [2, reject(e)];
                                        }
                                        break;
                                }
                                return [2];
                        }
                    });
                }); });
            };
            HttpServerShim.prototype.close = function () {
                var _this = this;
                if (this.state.closingPromise) {
                    return this.state.closingPromise;
                }
                this.state.closed = true;
                switch (this.config.type) {
                    case HttpBaseLib.EXPRESS:
                        this.state.closingPromise = (0, globals_ix_1.promise)(function (resolve) { return __awaiter(_this, void 0, void 0, function () {
                            var proms;
                            var _a, _b, _c;
                            return __generator(this, function (_d) {
                                switch (_d.label) {
                                    case 0:
                                        proms = [];
                                        try {
                                            this.beforeStop();
                                        }
                                        catch (e) {
                                            console.error(e);
                                        }
                                        try {
                                            (_c = (_b = (_a = this.baseLibData) === null || _a === void 0 ? void 0 : _a.express) === null || _b === void 0 ? void 0 : _b.server) === null || _c === void 0 ? void 0 : _c.close();
                                        }
                                        catch (e) {
                                            console.error(e);
                                        }
                                        try {
                                            proms.push(this.destroyAllWorkers());
                                        }
                                        catch (e) {
                                            console.error(e);
                                        }
                                        try {
                                            this.afterStop();
                                        }
                                        catch (e) {
                                            console.error(e);
                                        }
                                        return [4, globals_ix_1.PromUtil.allSettled(proms)];
                                    case 1:
                                        _d.sent();
                                        resolve();
                                        return [2];
                                }
                            });
                        }); });
                        break;
                }
                return this.state.closingPromise;
            };
            HttpServerShim.prototype.stamp = function (payload, encoding) {
                if (encoding === void 0) { encoding = 'ascii'; }
                return __awaiter(this, void 0, void 0, function () {
                    var payloadB64, sig;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (!payload) {
                                    payload = secure_channel_1.SecureHandshake.timeAuth();
                                }
                                if (typeof payload === 'string') {
                                    payloadB64 = Buffer.from(payload, encoding).toString('base64');
                                }
                                else {
                                    payloadB64 = payload.toString('base64');
                                }
                                return [4, this.pickWorker(http_shim_worker_security_1.SecureChannelWorkerClient).signMessage(payloadB64)];
                            case 1:
                                sig = _a.sent();
                                return [2, { payload: payloadB64, sig: sig }];
                        }
                    });
                });
            };
            HttpServerShim.prototype.prepareEncryptedOperation = function (op) {
                if (op.req.decryptedApiTarget) {
                    return (0, globals_ix_1.ok)(op.req.decryptedApiTarget);
                }
                var decryptResult = this.getDecryptedPayload(op);
                if (decryptResult.bad) {
                    return op.raise(decryptResult, HTTP.STATUS.UNAUTHORIZED);
                }
                if (!op.req.decryptedPayloadObject) {
                    return op.raise(http_models_1.HttpCode.BAD_REQUEST, "ENCRYPTED_OP_NON_JSON_PAYLOAD", "Supplied secure payload is not JSON format");
                }
                var args = op.req.decryptedPayloadObject;
                var resolved = this.pathResolve(args.path);
                if (!resolved) {
                    return op.raise(http_models_1.HttpCode.NOT_FOUND, "ENCRYPTED_OP_PATH_NOT_FOUND", "Encrypted access to unknown path: '".concat(args.path, "'"));
                }
                var api = resolved.methods[op.method];
                if (!api) {
                    return op.raise(http_models_1.HttpCode.NOT_FOUND, "ENCRYPTED_OP_METHOD_NOT_FOUND", "Method ".concat(op.method, " not found for '").concat(api.fullpath, "'"));
                }
                if (args.headers) {
                    Object.assign(op.req.headers, args);
                }
                op.params = op.req.params;
                var pathQueryParams = url.parse(args.path, true).query;
                if (Object.keys(resolved.params).length > 0) {
                    Object.assign(op.req.params, resolved.params);
                }
                if (Object.keys(pathQueryParams).length > 0) {
                    Object.assign(op.req.params, pathQueryParams);
                }
                if (args.body) {
                    try {
                        var data = JSON.parse(args.body);
                        op.req.data = data;
                        if (data && typeof data === 'object' && !Array.isArray(data)) {
                            Object.assign(op.req.params, data);
                        }
                    }
                    catch (e) {
                    }
                }
                op.req.decryptedApiTarget = api;
                return (0, globals_ix_1.ok)(api);
            };
            HttpServerShim.prototype.checkAccessor = function (op, forceVerify) {
                if (forceVerify === void 0) { forceVerify = false; }
                var authorizationHeader = op.req.getHeader('Accessor');
                var accessorConf = this.config.security.accessor;
                if (accessorConf.required || forceVerify) {
                    if (!authorizationHeader) {
                        return op.raise(http_models_1.HttpCode.UNAUTHORIZED, "ACCESSOR_HEADER_NOT_FOUND", "Accessor header does not exist");
                    }
                }
                else {
                    return (0, globals_ix_1.ok)({ accessor: null, t: 0, channelPublicKey: '' });
                }
                var authInfo = secure_channel_1.SecureHandshake.parseAuthHeader(authorizationHeader);
                var accessorExpression = authInfo.accessorExpression;
                var timeWindow = this.config.security.accessor.timeWindow;
                if (!accessorConf.baseTokenBuffer) {
                    accessorConf.baseTokenBuffer = Buffer.from(accessorConf.baseToken, 'ascii');
                }
                var accessDataResult = secure_channel_1.SecureHandshake.verifyAccessor(accessorExpression, accessorConf.baseTokenBuffer, timeWindow);
                if (accessDataResult.bad) {
                    return op.raise(accessDataResult, http_models_1.HttpCode.UNAUTHORIZED);
                }
                return (0, globals_ix_1.ok)(__assign(__assign({}, accessDataResult.data), { channelPublicKey: authInfo.peerEcdhPublicKey }));
            };
            HttpServerShim.prototype.getSecureChannel = function (op) {
                var accessInfoResult = this.checkAccessor(op, true);
                if (accessInfoResult.bad) {
                    return op.raise(accessInfoResult, HTTP.STATUS.BAD_REQUEST);
                }
                var channelId = accessInfoResult.data.channelPublicKey;
                var channel = this.secureChannels[channelId];
                if (!channel) {
                    return op.raise(http_models_1.HttpCode.UNAUTHORIZED, "SECURE_CHANNEL_NOT_FOUND", "secure channel not found: ".concat(channelId));
                }
                op.secureChannel = channel;
                return (0, globals_ix_1.ok)(channel);
            };
            HttpServerShim.prototype.getDecryptedPayload = function (op) {
                if (op.req.decryptedPayload) {
                    return (0, globals_ix_1.ok)(op.req.decryptedPayload);
                }
                var channelResult = this.getSecureChannel(op);
                if (channelResult.bad) {
                    return op.raise(channelResult, HTTP.STATUS.UNAUTHORIZED);
                }
                var channel = channelResult.data;
                var payload = channel.parseWrappedPayloadBase64(op.req.encryptedPayload);
                if (!payload || !payload.__scp) {
                    return op.raise(http_models_1.HttpCode.BAD_REQUEST, 'ENCRYPTED_OP_NO_SECURE_PAYLOAD', 'Secure payload not found');
                }
                op.req.decryptedPayload = channel.decryptSecureChannelPayloadIntoString(payload);
                if (isJsonString(op.req.decryptedPayload)) {
                    op.req.decryptedPayloadObject = JSON.parse(op.req.decryptedPayload);
                }
                return (0, globals_ix_1.ok)(op.req.decryptedPayload);
            };
            HttpServerShim.prototype.handlePre = function (op) {
                var _this = this;
                return (0, globals_ix_1.promise)(function (resolve) { return __awaiter(_this, void 0, void 0, function () {
                    var allPassed, _i, _a, preType, preFunc, passed;
                    var _b;
                    return __generator(this, function (_c) {
                        switch (_c.label) {
                            case 0:
                                allPassed = true;
                                if (!(((_b = op.api.pre) === null || _b === void 0 ? void 0 : _b.length) > 0)) return [3, 4];
                                _i = 0, _a = op.api.pre;
                                _c.label = 1;
                            case 1:
                                if (!(_i < _a.length)) return [3, 4];
                                preType = _a[_i];
                                preFunc = this.preHandler.byType[preType];
                                if (!preFunc) {
                                    return [3, 3];
                                }
                                return [4, preFunc.apply(this.preHandler, [op])];
                            case 2:
                                passed = _c.sent();
                                if (!passed) {
                                    allPassed = false;
                                    return [3, 4];
                                }
                                _c.label = 3;
                            case 3:
                                _i++;
                                return [3, 1];
                            case 4:
                                resolve(allPassed);
                                return [2];
                        }
                    });
                }); });
            };
            HttpServerShim.prototype.handlePost = function (op) {
                var _this = this;
                return (0, globals_ix_1.promise)(function (resolve) { return __awaiter(_this, void 0, void 0, function () {
                    var allPassed, _i, _a, postType, postFunc, passed;
                    return __generator(this, function (_b) {
                        switch (_b.label) {
                            case 0:
                                allPassed = true;
                                if (!op.api.post) return [3, 4];
                                _i = 0, _a = op.api.post;
                                _b.label = 1;
                            case 1:
                                if (!(_i < _a.length)) return [3, 4];
                                postType = _a[_i];
                                postFunc = this.postHandler.byType[postType];
                                if (!postFunc) {
                                    return [3, 3];
                                }
                                return [4, postFunc.apply(this.postHandler, [op])];
                            case 2:
                                passed = _b.sent();
                                if (!passed) {
                                    allPassed = false;
                                    return [3, 4];
                                }
                                _b.label = 3;
                            case 3:
                                _i++;
                                return [3, 1];
                            case 4:
                                resolve(allPassed);
                                return [2];
                        }
                    });
                }); });
            };
            HttpServerShim.prototype.pathResolve = function (path, newApi) {
                if (newApi === void 0) { newApi = null; }
                var paths = path.split('/');
                if (paths[0] === '') {
                    paths.shift();
                }
                var paramCollector = {};
                var node = this.pathTree;
                for (var _i = 0, paths_1 = paths; _i < paths_1.length; _i++) {
                    var pathSlot = paths_1[_i];
                    var slot = decodeURIComponent(pathSlot.split('?')[0].split('#')[0]);
                    if (slot === '__apidef__') {
                        return null;
                    }
                    var isParam = slot.startsWith(':');
                    if (node[slot]) {
                        node = node[slot];
                        continue;
                    }
                    var paramDef = node['?param-name?'];
                    if (paramDef) {
                        if (newApi && isParam && paramDef.slot !== slot) {
                            throw new Error("Cannot register a parameter slot ".concat(slot, ", ") +
                                "parameter ".concat(paramDef.slot, " has been registered by ").concat(paramDef.registeredPath));
                        }
                        paramCollector[paramDef.name] = slot;
                        node = paramDef.nextNode;
                        continue;
                    }
                    if (newApi) {
                        var nextNode = {};
                        if (isParam) {
                            node['?param-name?'] = { nextNode: nextNode, slot: slot, name: slot.substr(1), registeredPath: path };
                        }
                        node[slot] = nextNode;
                        node = node[slot];
                    }
                    else {
                        return null;
                    }
                }
                if (!node) {
                    return null;
                }
                if (newApi) {
                    if (node.__apidef__ && node.__apidef__.methods[newApi.method]) {
                        throw new Error("Cannot register api at ".concat(newApi.method, " ").concat(path, ", another api is already registered"));
                    }
                    if (!node.__apidef__) {
                        node.__apidef__ = {
                            type: 'api',
                            path: path,
                            registeredPath: path,
                            methods: {},
                            params: {},
                        };
                    }
                    node.__apidef__.methods[newApi.method] = newApi;
                    return node.__apidef__;
                }
                var registeredDef = node.__apidef__;
                if (!registeredDef) {
                    return null;
                }
                return {
                    type: 'api',
                    path: path,
                    methods: registeredDef.methods,
                    registeredPath: registeredDef.registeredPath,
                    params: paramCollector,
                };
            };
            HttpServerShim.prototype.destroyAllWorkers = function () {
                var proms = [];
                for (var _i = 0, _a = Object.keys(this.workerFleet); _i < _a.length; _i++) {
                    var workerClass = _a[_i];
                    var fleet = this.workerFleet[workerClass];
                    for (var _b = 0, _c = fleet.workers; _b < _c.length; _b++) {
                        var worker = _c[_b];
                        var terminationProm = worker.terminate();
                        proms.push(terminationProm);
                        process_exit_handler_1.ProcessExit.gracefulExitPromises.push(terminationProm);
                    }
                }
                this.workerFleet = {};
                return globals_ix_1.PromUtil.allSettled(proms);
            };
            return HttpServerShim;
        }()),
        (function () {
            _getRoles_decorators = [HTTP.GET('/test-roles-api', { rootMount: true }), HTTP.ACCESS({ ADMIN: true, NO_AUTH: true })];
            _getServerPublicInfo_decorators = [HTTP.GET(HTTP.SHIM.ROOT_API_PUBLIC_INFO, { rootMount: true })];
            _newSecureChannel_decorators = [HTTP.GET(HTTP.SHIM.ROOT_API_NEW_CHANNEL, { rootMount: true })];
            _encryptedOperation_decorators = [HTTP.METHODS(http_models_1.httpRest, HTTP.SHIM.ROOT_API_SECURE_API, { rootMount: true })];
            _proxyRequestOperation_decorators = [HTTP.GET(HTTP.SHIM.ROOT_API_PROXY_REQUEST, { rootMount: true })];
            __esDecorate(_b, null, _getRoles_decorators, { kind: "method", name: "getRoles", static: false, private: false, access: { has: function (obj) { return "getRoles" in obj; }, get: function (obj) { return obj.getRoles; } } }, null, _instanceExtraInitializers);
            __esDecorate(_b, null, _getServerPublicInfo_decorators, { kind: "method", name: "getServerPublicInfo", static: false, private: false, access: { has: function (obj) { return "getServerPublicInfo" in obj; }, get: function (obj) { return obj.getServerPublicInfo; } } }, null, _instanceExtraInitializers);
            __esDecorate(_b, null, _newSecureChannel_decorators, { kind: "method", name: "newSecureChannel", static: false, private: false, access: { has: function (obj) { return "newSecureChannel" in obj; }, get: function (obj) { return obj.newSecureChannel; } } }, null, _instanceExtraInitializers);
            __esDecorate(_b, null, _encryptedOperation_decorators, { kind: "method", name: "encryptedOperation", static: false, private: false, access: { has: function (obj) { return "encryptedOperation" in obj; }, get: function (obj) { return obj.encryptedOperation; } } }, null, _instanceExtraInitializers);
            __esDecorate(_b, null, _proxyRequestOperation_decorators, { kind: "method", name: "proxyRequestOperation", static: false, private: false, access: { has: function (obj) { return "proxyRequestOperation" in obj; }, get: function (obj) { return obj.proxyRequestOperation; } } }, null, _instanceExtraInitializers);
        })(),
        _b;
}();
var HttpRequest = (function () {
    function HttpRequest(op) {
        this.body = null;
        this.bodyRaw = null;
        this.headers = {};
        this.t = Date.now();
        this.op = op;
    }
    HttpRequest.prototype.getHeader = function (headerName) {
        switch (this.op.server.config.type) {
            case HttpBaseLib.EXPRESS:
                return this.op.oriReq.header(headerName);
            default:
                return null;
        }
    };
    return HttpRequest;
}());
exports.HttpRequest = HttpRequest;
var HttpResponse = (function () {
    function HttpResponse(op) {
        this.headers = {};
        this.t = -1;
        this.dt = -1;
        this.ended = false;
        this.output = [];
        this.endingPayload = '';
        this.endingPayloadRaw = '';
        this.statusCode = 200;
        this.appErrorCode = 'GENERIC_ERROR';
        this.onends = [];
        this.op = op;
    }
    Object.defineProperty(HttpResponse.prototype, "onend", {
        get: function () { return this.onends; },
        enumerable: false,
        configurable: true
    });
    HttpResponse.prototype.send = function (payload) {
        if (this.ended) {
            return;
        }
        this.op.oriRes.send(payload);
        this.output.push(payload);
        return this;
    };
    HttpResponse.prototype.end = function (payload, returnValue) {
        if (this.ended) {
            return;
        }
        this.ended = true;
        this.t = Date.now();
        this.dt = this.t - this.req.t;
        for (var _i = 0, _b = this.onends; _i < _b.length; _i++) {
            var onend = _b[_i];
            try {
                if (onend) {
                    onend();
                }
            }
            catch (e) { }
        }
        this.endingPayload = payload;
        this.output.push(payload);
        if (returnValue !== undefined) {
            this.returnValue = returnValue;
        }
        return this;
    };
    HttpResponse.prototype.status = function (num) {
        this.statusCode = num;
        return this;
    };
    HttpResponse.prototype.returnCached = function (code, cached) {
        this.statusCode = code;
        return this.end(cached);
    };
    HttpResponse.prototype.returnNotOk = function (code, message) {
        if (message === void 0) { message = ''; }
        var statusName = 'unclassified_server_error';
        switch (code) {
            case 400:
                statusName = 'bad_request';
                break;
            case 401:
                statusName = 'unauthorized';
                break;
            case 404:
                statusName = 'not_found';
                break;
            case 500:
                statusName = 'internal_server_error';
                break;
        }
        var resObj = { status: statusName, message: message };
        if (!message && this.op.errors.length > 0) {
            var e = this.op.errors[0].e;
            message = e.message;
            if (this.op.server.config.debug.showErrorStack) {
                resObj.stackTrace = e.stack;
            }
        }
        this.statusCode = code;
        return this.end(JSON.stringify(resObj));
    };
    HttpResponse.prototype.okJsonPreserialized = function (serial) { return "{\"status\":\"ok\",\"result\":".concat(serial, "}"); };
    HttpResponse.prototype.okJsonString = function (obj) { return JSON.stringify({ status: 'ok', result: obj }); };
    HttpResponse.prototype.returnJsonPreserialized = function (serialized, original) {
        this.end("{\"status\":\"ok\",\"result\":".concat(serialized, "}"));
        return original;
    };
    HttpResponse.prototype.returnJson = function (obj) {
        this.end(JSON.stringify({ status: 'ok', result: obj }), obj);
        return obj;
    };
    return HttpResponse;
}());
exports.HttpResponse = HttpResponse;
var HttpPathResolution = (function () {
    function HttpPathResolution() {
    }
    return HttpPathResolution;
}());
exports.HttpPathResolution = HttpPathResolution;
var HttpOp = (function () {
    function HttpOp(server, api, oriReq, oriRes) {
        if (oriReq === void 0) { oriReq = null; }
        if (oriRes === void 0) { oriRes = null; }
        this.server = server;
        this.api = api;
        this.oriReq = oriReq;
        this.oriRes = oriRes;
        this.error = null;
        this.errors = [];
        this.pendingSequential = [];
        this.pendingParallel = [];
        this.params = {};
        this.req = new HttpRequest(this);
        this.req.params = this.params;
        this.res = new HttpResponse(this);
        this.res.req = this.req;
        this.req.res = this.res;
        this.cache = new HttpCacheOp(this);
    }
    HttpOp.prototype.raise = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        if (typeof args[0] === 'number') {
            var _b = args, statusCode = _b[0], errorCode = _b[1], message = _b[2];
            if (!this.res.ended) {
                this.res.returnNotOk(statusCode, message);
            }
            return exports.HttpShimCode.error(errorCode, message, { statusCode: statusCode });
        }
        else {
            if (args[0] instanceof Error) {
                args[0] = (0, globals_ix_1.errorResult)(args[0]);
            }
            var _c = args, result = _c[0], statusCode = _c[1];
            if (result.ok) {
                if (!statusCode) {
                    statusCode = result.statusCode ? result.statusCode : 200;
                }
                if (!this.res.ended) {
                    this.res.status(statusCode).returnJson(result.data);
                }
            }
            else {
                if (!statusCode) {
                    statusCode = result.statusCode ? result.statusCode : 500;
                }
                if (!this.res.ended) {
                    this.res.returnNotOk(statusCode, result.message);
                }
            }
            return result;
        }
    };
    HttpOp.prototype.returnJson = function (obj) {
        var status = 'ok';
        var result = obj;
        if (obj && obj.isResultKind) {
            var res = obj;
            if (res.bad) {
                status = 'error';
                result = res.message;
            }
            else {
                result = res.data;
            }
            if (res.statusCode) {
                this.res.status(res.statusCode);
            }
        }
        if (status === 'error') {
            return this.res.end(JSON.stringify({ status: status, message: result, server: this.server.config.name }), obj);
        }
        else {
            return this.res.end(JSON.stringify({ status: status, result: result, server: this.server.config.name }), obj);
        }
    };
    HttpOp.prototype.setResponse = function (endingPayload) {
        if (endingPayload) {
            this.res.endingPayload = endingPayload;
        }
    };
    HttpOp.prototype.addSequentialProcess = function (proc) {
        this.pendingSequential.push(proc);
        return proc;
    };
    HttpOp.prototype.waitFor = function (resolver) {
        var proc = new Promise(resolver);
        this.pendingSequential.push(proc);
        return proc;
    };
    HttpOp.prototype.run = function (fromInternal) {
        if (fromInternal === void 0) { fromInternal = false; }
        return __awaiter(this, void 0, void 0, function () {
            var preRes, _i, _b, prom;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        this.fromInternal = fromInternal;
                        return [4, this.server.handlePre(this)];
                    case 1:
                        preRes = _c.sent();
                        if (!preRes) return [3, 6];
                        return [4, this.server[this.api.handlerName](this)];
                    case 2:
                        _c.sent();
                        _i = 0, _b = this.pendingSequential;
                        _c.label = 3;
                    case 3:
                        if (!(_i < _b.length)) return [3, 6];
                        prom = _b[_i];
                        return [4, Promise.resolve(prom)];
                    case 4:
                        _c.sent();
                        _c.label = 5;
                    case 5:
                        _i++;
                        return [3, 3];
                    case 6: return [4, this.server.handlePost(this)];
                    case 7:
                        _c.sent();
                        if (this.secureChannel) {
                            this.res.endingPayloadRaw = this.res.endingPayload;
                            this.res.endingPayload = JSON.stringify({
                                status: 'ok',
                                format: 'json',
                                encrypted: true,
                                payload: this.secureChannel.createWrappedPayload(this.res.endingPayload),
                            });
                        }
                        this.finish();
                        return [2];
                }
            });
        });
    };
    HttpOp.prototype.finish = function () {
        switch (this.server.config.type) {
            case HttpBaseLib.EXPRESS:
                this.oriRes.status(this.res.statusCode).end(this.res.endingPayload);
                return null;
            default:
                throw new Error("Unknown base http library type: ".concat(this.server.config.type));
        }
    };
    return HttpOp;
}());
exports.HttpOp = HttpOp;
var PreHandler = (function () {
    function PreHandler() {
        var _b;
        this.byType = {};
        this.byType = (_b = {},
            _b[ReqProcessor.DECRYPT] = this.optionalDecrypt,
            _b[ReqProcessor.AUTH] = this.auth,
            _b[ReqProcessor.BASIC] = this.basic,
            _b);
    }
    PreHandler.prototype.auth = function (op) {
        return __awaiter(this, void 0, void 0, function () {
            var _this = this;
            return __generator(this, function (_b) {
                return [2, (0, globals_ix_1.promise)(function (resolve) { return __awaiter(_this, void 0, void 0, function () {
                        var srvConfig, authData, apiRoleBook, headerText, _b, signedType, scheme, payloadBase64, sigBase64, publicKey, found, _i, _c, authServerKey, verifyResult, roleData, targetRoleKey, rolesApplicable, _d, _e, role;
                        var _f;
                        return __generator(this, function (_g) {
                            srvConfig = op.server.config;
                            if (srvConfig.security.noauth) {
                                return [2, resolve(true)];
                            }
                            switch (srvConfig.type) {
                                case HttpBaseLib.EXPRESS:
                                    authData = op.oriReq.headers.authorization;
                                    apiRoleBook = op.server.apiAccess[op.api.handlerName];
                                    if (!op.fromInternal && (apiRoleBook === null || apiRoleBook === void 0 ? void 0 : apiRoleBook['deny-all'])) {
                                        op.returnJson(exports.HttpShimCode.error('AUTH_HEADER_SIGNED_BUT_API_DENIES_ALL', "API '".concat(op.api.method, " ").concat(op.api.fullpath, "' is set to deny-all")));
                                    }
                                    if (authData) {
                                        if (authData.startsWith('Bearer ')) {
                                            headerText = authData.split('Bearer ')[1];
                                            if (headerText.startsWith('SIGNED.')) {
                                                _b = headerText.split('.'), signedType = _b[0], scheme = _b[1], payloadBase64 = _b[2], sigBase64 = _b[3], publicKey = _b[4];
                                                if (scheme === 'ECC_4Q') {
                                                    found = false;
                                                    for (_i = 0, _c = Object.keys(op.server.authServers); _i < _c.length; _i++) {
                                                        authServerKey = _c[_i];
                                                        if (op.server.authServers[authServerKey].publicKey === publicKey) {
                                                            found = true;
                                                            break;
                                                        }
                                                    }
                                                    if (!found) {
                                                        op.returnJson(exports.HttpShimCode.error('AUTH_HEADER_SIGNED_BUT_PUBLIC_KEY_NOT_FOUND'));
                                                        return [2, resolve(false)];
                                                    }
                                                    verifyResult = secure_channel_1.SecureHandshake.verifyStamp({ payload: payloadBase64, sig: sigBase64 }, publicKey);
                                                    if (verifyResult.bad) {
                                                        op.returnJson(verifyResult);
                                                        return [2, resolve(false)];
                                                    }
                                                    try {
                                                        roleData = JSON.parse(Buffer.from(payloadBase64, 'base64').toString('utf8'));
                                                        op.user = {
                                                            username: roleData.name,
                                                            publicKeys: roleData.publicKey,
                                                            roles: roleData.server[op.server.config.name],
                                                            rolesApplicable: null,
                                                        };
                                                        targetRoleKey = void 0;
                                                        if (apiRoleBook && !apiRoleBook['allow-all']) {
                                                            targetRoleKey = Object.keys(apiRoleBook);
                                                            rolesApplicable = [];
                                                            for (_d = 0, _e = op.user.roles; _d < _e.length; _d++) {
                                                                role = _e[_d];
                                                                if (apiRoleBook[role]) {
                                                                    rolesApplicable.push(role);
                                                                }
                                                            }
                                                            op.user.rolesApplicable = rolesApplicable;
                                                            if (!((_f = op.user.rolesApplicable) === null || _f === void 0 ? void 0 : _f.length)) {
                                                                op.returnJson(exports.HttpShimCode.error('AUTH_HEADER_SIGNED_ROLE_UNAUTHORZIED_FOR_API', "API '".concat(op.api.method, " ").concat(op.api.fullpath, "' as user '").concat(op.user.username, "' with roles [").concat(op.user.roles.join(', '), "] ") +
                                                                    "has no authorizable match for the API requiring [".concat(targetRoleKey.join(', '), "]")));
                                                                return [2, resolve(false)];
                                                            }
                                                        }
                                                    }
                                                    catch (e) {
                                                        op.returnJson(exports.HttpShimCode.error('AUTH_HEADER_SIGNED_NO_ROLES_MAP'));
                                                        return [2, resolve(false)];
                                                    }
                                                    return [2, resolve(true)];
                                                }
                                            }
                                            else if (headerText.startsWith('SYMNT_HASH.')) {
                                            }
                                        }
                                        op.returnJson(exports.HttpShimCode.error('AUTH_HEADER_NOT_VALID'));
                                        return [2, resolve(false)];
                                    }
                                    else {
                                        op.returnJson(exports.HttpShimCode.error('AUTH_HEADER_NOT_FOUND'));
                                        return [2, resolve(false)];
                                    }
                                    break;
                            }
                            return [2];
                        });
                    }); })];
            });
        });
    };
    PreHandler.prototype.basic = function (op) {
        return __awaiter(this, void 0, void 0, function () {
            var _this = this;
            return __generator(this, function (_b) {
                return [2, (0, globals_ix_1.promise)(function (resolve) { return __awaiter(_this, void 0, void 0, function () {
                        var errored_1, chunks_1;
                        return __generator(this, function (_b) {
                            switch (op.server.config.type) {
                                case HttpBaseLib.EXPRESS:
                                    op.oriRes.header('Content-Type', 'application/json');
                                    errored_1 = false;
                                    chunks_1 = [];
                                    op.oriReq.on('data', function (chunk) {
                                        chunks_1.push(chunk);
                                    });
                                    op.oriReq.on('end', function () {
                                        try {
                                            op.req.params = op.oriReq.params ? op.oriReq.params : {};
                                            var queryParamNames = void 0;
                                            if (op.oriReq.query && (queryParamNames = Object.keys(op.oriReq.query)).length > 0) {
                                                for (var _i = 0, queryParamNames_1 = queryParamNames; _i < queryParamNames_1.length; _i++) {
                                                    var queryParamName = queryParamNames_1[_i];
                                                    op.req.params[queryParamName] = op.oriReq.query[queryParamName];
                                                }
                                            }
                                            op.req.bodyRaw = Buffer.concat(chunks_1);
                                            var bod = op.req.body = op.req.bodyRaw.toString();
                                            if (op.oriReq.headers['encrypted-api']) {
                                                op.req.encryptedPayload = bod;
                                                var prepareResult = op.server.prepareEncryptedOperation(op);
                                                if (prepareResult.bad) {
                                                    op.raise(prepareResult);
                                                    return resolve(false);
                                                }
                                            }
                                            else {
                                                op.params = op.req.params;
                                                op.req.body = op.req.bodyRaw.toString();
                                                if (isJsonString(op.req.body)) {
                                                    try {
                                                        op.req.data = JSON.parse(op.req.body);
                                                        if (typeof op.req.data === 'object' && !Array.isArray(op.req.data)) {
                                                            Object.assign(op.req.params, op.req.data);
                                                        }
                                                    }
                                                    catch (e) {
                                                        console.error('BAD_JSON', e);
                                                    }
                                                }
                                            }
                                            resolve(true);
                                        }
                                        catch (e) {
                                            console.error(e);
                                        }
                                    });
                                    op.oriReq.on('error', function (e) {
                                        console.error(e);
                                        errored_1 = true;
                                        resolve(false);
                                    });
                                    break;
                            }
                            return [2];
                        });
                    }); })];
            });
        });
    };
    PreHandler.prototype.optionalDecrypt = function (op) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_b) {
                return [2, new Promise(function (resolve) {
                    })];
            });
        });
    };
    return PreHandler;
}());
exports.PreHandler = PreHandler;
var PostHandler = (function () {
    function PostHandler() {
        var _b;
        this.byType = {};
        this.byType = (_b = {},
            _b[ReqProcessor.BASIC] = this.basic,
            _b[ReqProcessor.ENCRYPT] = this.optionalEncrypt,
            _b);
    }
    PostHandler.prototype.basic = function (op) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_b) {
                return [2, new Promise(function (resolve) {
                        switch (op.server.config.type) {
                            case HttpBaseLib.EXPRESS:
                                resolve(true);
                                break;
                        }
                    })];
            });
        });
    };
    PostHandler.prototype.optionalEncrypt = function (op) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_b) {
                return [2, new Promise(function (resolve) {
                        switch (op.server.config.type) {
                            case HttpBaseLib.EXPRESS:
                                resolve(true);
                                break;
                        }
                    })];
            });
        });
    };
    return PostHandler;
}());
exports.PostHandler = PostHandler;
var CacheParser;
(function (CacheParser) {
    CacheParser["JSON"] = "JSON";
})(CacheParser = exports.CacheParser || (exports.CacheParser = {}));
var CacheDef = (function () {
    function CacheDef(init) {
        this.keys = null;
        this.keysExceptLast = null;
        this.lastKey = null;
        this.maxOld = 0;
        this.matchExactly = false;
        this.defStack = '';
        if (init) {
            Object.assign(this, init);
        }
        if (this.path.indexOf('/') >= 0) {
            this.keys = [];
            var keys = this.path.split('/').slice(1);
            for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
                var keyname = keys_1[_i];
                if (keyname.startsWith(':')) {
                    this.keys.push({ name: keyname.split(':')[1], type: 'param' });
                }
                else {
                    this.keys.push({ name: keyname, type: 'fixed' });
                }
            }
            this.lastKey = this.keys[this.keys.length - 1];
            this.keysExceptLast = this.keys.slice(0, -1);
        }
        if (!this.serializer) {
            this.serializer = CacheParser.JSON;
        }
    }
    return CacheDef;
}());
exports.CacheDef = CacheDef;
var CacheEntry = (function () {
    function CacheEntry(init) {
        if (init) {
            Object.assign(this, init);
        }
    }
    CacheEntry.prototype.asResponse = function () {
        if (this.serializedResponse) {
            return this.serializedResponse;
        }
    };
    CacheEntry.prototype.asSerialized = function () { return this.serialized; };
    CacheEntry.prototype.getData = function (option) {
        var nav = this.keyNavigate(option);
        return nav.target[nav.key];
    };
    CacheEntry.prototype.keyNavigate = function (option) {
        if (this.def.keys) {
            if (!this.rootNode) {
                this.rootNode = {};
            }
            var node = this.rootNode;
            for (var _i = 0, _b = this.def.keysExceptLast; _i < _b.length; _i++) {
                var keyInfo = _b[_i];
                var key = this.resolvePathKey(keyInfo, option);
                if (!node[key]) {
                    node[key.name] = {};
                }
                node = node[key];
            }
            var lastKeyStr = this.resolvePathKey(this.def.lastKey, option);
            return { key: lastKeyStr, target: node };
        }
        else {
            return { key: 'value', target: this };
        }
    };
    CacheEntry.prototype.resolvePathKey = function (keyInfo, opt) {
        var _b;
        var key;
        if (keyInfo.type === 'fixed') {
            key = keyInfo.name;
        }
        else {
            if (!(opt === null || opt === void 0 ? void 0 : opt.pathParams)) {
                throw new Error("Cannot naviagate cache path '".concat(this.def.path, "'. param not given"));
            }
            var paramValue = (_b = opt === null || opt === void 0 ? void 0 : opt.pathParams) === null || _b === void 0 ? void 0 : _b[keyInfo.name];
            if (!paramValue) {
                throw new Error("Cannot naviagate cache path '".concat(this.def.path, "'. param '").concat(keyInfo.name, "' not found"));
            }
            key = paramValue;
        }
        if (!key) {
            throw new Error("Cannot naviagate cache path '".concat(this.def.path, "; Params = ").concat(opt.pathParams));
        }
        return key;
    };
    return CacheEntry;
}());
exports.CacheEntry = CacheEntry;
var HttpCacheOp = (function () {
    function HttpCacheOp(op) {
        this.op = op;
    }
    HttpCacheOp.prototype.handler = function (cacheDef, option, dataResolver) {
        return __awaiter(this, void 0, void 0, function () {
            var entry, matched;
            var _this = this;
            return __generator(this, function (_b) {
                if (!option) {
                    option = {};
                }
                if (!option.pathParams) {
                    option.pathParams = {};
                }
                if (this.op.req.params) {
                    Object.assign(option.pathParams, this.op.req.params);
                }
                entry = this.cacheEntryGet(cacheDef, option);
                matched = entry ? true : false;
                return [2, this.op.addSequentialProcess(new Promise(function (procResolve) {
                        var resolve = function (data, cacheEntry) {
                            if (matched && (cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.serializedResponse)) {
                                _this.op.setResponse(cacheEntry.serializedResponse);
                                return procResolve();
                            }
                            var dataString;
                            var responseString;
                            switch (cacheDef.serializer) {
                                case CacheParser.JSON:
                                    dataString = option.serialized = JSON.stringify(data);
                                    responseString = option.serializedResponse = _this.op.res.okJsonPreserialized(dataString);
                                    break;
                            }
                            _this.cacheSet(cacheDef, data, option);
                            _this.op.setResponse(responseString);
                            return procResolve();
                        };
                        var reject = function (result) {
                            _this.op.raise(result);
                            return procResolve();
                        };
                        if (matched) {
                            resolve(entry.getData(option), entry);
                        }
                        else {
                            try {
                                dataResolver(resolve, reject);
                            }
                            catch (e) {
                                _this.op.raise(exports.HttpShimCode.error('CACHE_DATA_FETCH_FAILED'), http_models_1.HttpCode.INTERNAL_SERVER_ERROR);
                                return procResolve();
                            }
                        }
                    }))];
            });
        });
    };
    HttpCacheOp.prototype.cacheEntryGet = function (cacheDef, option) {
        var cacheData = this.op.server.cacheData[cacheDef.path];
        if (!cacheData || !cacheData.hasValue) {
            return null;
        }
        var matchExactly = cacheDef.matchExactly ? true : (option.matchExactly ? true : false);
        if (matchExactly) {
            if (option && option.version && option.version !== cacheData.version) {
                return null;
            }
        }
        else {
            if (cacheData.def.maxOld !== 0 &&
                Date.now() - cacheData.version > cacheData.def.maxOld) {
                return null;
            }
        }
        ++cacheData.hits;
        return cacheData;
    };
    HttpCacheOp.prototype.cacheSet = function (cacheDef, value, option) {
        if (!this.op.server.cacheData[cacheDef.path]) {
            throw new Error("Cache key '".concat(cacheDef.path, "' is not defined ahead-of-time for this server."));
        }
        var cacheData = this.op.server.cacheData[cacheDef.path];
        var setter = cacheData.keyNavigate(option);
        setter.target[setter.key] = value;
        if (option === null || option === void 0 ? void 0 : option.version) {
            cacheData.version = option.version;
        }
        else {
            cacheData.version = Date.now();
        }
        if (option === null || option === void 0 ? void 0 : option.serialized) {
            cacheData.serialized = option.serialized;
        }
        if (option === null || option === void 0 ? void 0 : option.serializedResponse) {
            cacheData.serializedResponse = option.serializedResponse;
        }
        cacheData.hasValue = true;
        return cacheData;
    };
    HttpCacheOp.prototype.cacheUnset = function (cacheDef) {
        var cacheData = this.op.server.cacheData[cacheDef.path];
        if (cacheData) {
            cacheData.hasValue = false;
        }
        return cacheData;
    };
    return HttpCacheOp;
}());
exports.HttpCacheOp = HttpCacheOp;
function expressHandler(server, api) {
    var _this = this;
    return function (oriReq, oriRes) { return __awaiter(_this, void 0, void 0, function () {
        var op;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    op = new HttpOp(server, api, oriReq, oriRes);
                    op.method = oriReq.method;
                    return [4, op.run()];
                case 1:
                    _b.sent();
                    return [2];
            }
        });
    }); };
}
function isJsonString(str) {
    return (str.startsWith('{') && str.endsWith('}')) || (str.startsWith('[') && str.endsWith(']'));
}
//# sourceMappingURL=http.shim.js.map