"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Request = exports.createServiceError = exports.defaultExtractor = void 0;
var Route_1 = require("../Services/Route");
var BringgException_1 = require("./BringgException");
var ExceptionReason_1 = require("./ExceptionReason");
var defaultExtractor = function (response) { return response; };
exports.defaultExtractor = defaultExtractor;
/**
 * Creates an "unsuccessful result" BringgException with a manually initialized stack trace.
 * @param exception The error message.
 * @param stackConstructor Optionally provide the error factory function, so it will be omitted from the stack if possible.
 */
function createServiceError(exception, stackConstructor) {
    if (stackConstructor === void 0) { stackConstructor = createServiceError; }
    var generatedException = new BringgException_1.BringgException(ExceptionReason_1.ExceptionReason.UNSUCCESSFUL_RESULT, exception);
    // Not available on browser, only nodejs.
    if (Error.captureStackTrace) {
        // keep only the frames that happened before calling createServiceError
        Error.captureStackTrace(generatedException, stackConstructor);
    }
    else {
        // If no start stack function was provided we just use the original stack property
        // The stack trace is created on error construction.
        var errorWithStack = new Error();
        generatedException.stack = errorWithStack.stack;
    }
    return generatedException;
}
exports.createServiceError = createServiceError;
var Request = /** @class */ (function () {
    function Request(service, route) {
        this.service = service;
        this.route = route;
        this.extractor = exports.defaultExtractor;
    }
    Request.prototype.withRouteParams = function (routeParams) {
        this.routeParams = routeParams;
        return this;
    };
    Request.prototype.withQueryString = function (queryString) {
        this.queryString = queryString;
        return this;
    };
    Request.prototype.withExtractor = function (extractor) {
        this.extractor = extractor;
        return this;
    };
    Request.prototype.withPayload = function (payload) {
        this.payload = payload;
        return this;
    };
    Request.prototype.withHeaders = function (headers) {
        this.headers = headers;
        return this;
    };
    Request.prototype.withResponseType = function (responseType) {
        this.responseType = responseType;
        return this;
    };
    Request.prototype.withCommonOptions = function (commonOptions) {
        this.signal = commonOptions === null || commonOptions === void 0 ? void 0 : commonOptions.signal;
        return this;
    };
    Request.prototype.setException = function (exception) {
        // Generating the exception here as we want to get stack trace with the relevant data
        // if generating the error inside the exception function all calls before setException won't exist
        // because of V8 zero-cost async stack trace
        var generatedException = createServiceError(exception, this.setException);
        this.exception = function () { return generatedException; };
        return this;
    };
    Request.prototype.invoke = function () {
        return this.service.handleAuthorizedRequest({
            route: this.route,
            extractor: this.extractor,
            exceptionProducer: this.exception,
            payload: this.payload,
            routeParams: this.routeParams,
            queryString: this.queryString,
            headers: this.headers,
            responseType: this.responseType,
            signal: this.signal
        });
    };
    return Request;
}());
exports.Request = Request;
var RouteGenerator = /** @class */ (function () {
    function RouteGenerator(service) {
        this.service = service;
    }
    RouteGenerator.prototype.get = function (routeName) {
        var route = new Route_1.Route(routeName, 0 /* HttpMethod.GET */);
        return new Request(this.service, route);
    };
    RouteGenerator.prototype.post = function (routeName) {
        var route = new Route_1.Route(routeName, 1 /* HttpMethod.POST */);
        return new Request(this.service, route);
    };
    RouteGenerator.prototype.put = function (routeName) {
        var route = new Route_1.Route(routeName, 2 /* HttpMethod.PUT */);
        return new Request(this.service, route);
    };
    RouteGenerator.prototype.patch = function (routeName) {
        var route = new Route_1.Route(routeName, 3 /* HttpMethod.PATCH */);
        return new Request(this.service, route);
    };
    RouteGenerator.prototype.delete = function (routeName) {
        var route = new Route_1.Route(routeName, 4 /* HttpMethod.DELETE */);
        return new Request(this.service, route);
    };
    return RouteGenerator;
}());
exports.default = RouteGenerator;
//# sourceMappingURL=RouteGenerator.js.map