import { __assign, __extends } from "tslib";
import { BaseBackend, getCurrentHub } from '@sentry/core';
import { Severity } from '@sentry/types';
import { addExceptionMechanism, addExceptionTypeValue, Dsn, extractExceptionKeysForMessage, isError, isPlainObject, normalizeToSize, SyncPromise, } from '@sentry/utils';
import { extractStackFromError, parseError, parseStack, prepareFramesForEvent } from './parsers';
import { HTTPSTransport, HTTPTransport } from './transports';
/**
 * The Sentry Node SDK Backend.
 * @hidden
 */
var NodeBackend = /** @class */ (function (_super) {
    __extends(NodeBackend, _super);
    function NodeBackend() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * @inheritDoc
     */
    // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
    NodeBackend.prototype.eventFromException = function (exception, hint) {
        var _this = this;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        var ex = exception;
        var mechanism = {
            handled: true,
            type: 'generic',
        };
        if (!isError(exception)) {
            if (isPlainObject(exception)) {
                // This will allow us to group events based on top-level keys
                // which is much better than creating new group when any key/value change
                var message = "Non-Error exception captured with keys: " + extractExceptionKeysForMessage(exception);
                getCurrentHub().configureScope(function (scope) {
                    scope.setExtra('__serialized__', normalizeToSize(exception));
                });
                ex = (hint && hint.syntheticException) || new Error(message);
                ex.message = message;
            }
            else {
                // This handles when someone does: `throw "something awesome";`
                // We use synthesized Error here so we can extract a (rough) stack trace.
                ex = (hint && hint.syntheticException) || new Error(exception);
                ex.message = exception;
            }
            mechanism.synthetic = true;
        }
        return new SyncPromise(function (resolve, reject) {
            return parseError(ex, _this._options)
                .then(function (event) {
                addExceptionTypeValue(event, undefined, undefined);
                addExceptionMechanism(event, mechanism);
                resolve(__assign(__assign({}, event), { event_id: hint && hint.event_id }));
            })
                .then(null, reject);
        });
    };
    /**
     * @inheritDoc
     */
    NodeBackend.prototype.eventFromMessage = function (message, level, hint) {
        var _this = this;
        if (level === void 0) { level = Severity.Info; }
        var event = {
            event_id: hint && hint.event_id,
            level: level,
            message: message,
        };
        return new SyncPromise(function (resolve) {
            if (_this._options.attachStacktrace && hint && hint.syntheticException) {
                var stack = hint.syntheticException ? extractStackFromError(hint.syntheticException) : [];
                parseStack(stack, _this._options)
                    .then(function (frames) {
                    event.stacktrace = {
                        frames: prepareFramesForEvent(frames),
                    };
                    resolve(event);
                })
                    .then(null, function () {
                    resolve(event);
                });
            }
            else {
                resolve(event);
            }
        });
    };
    /**
     * @inheritDoc
     */
    NodeBackend.prototype._setupTransport = function () {
        if (!this._options.dsn) {
            // We return the noop transport here in case there is no Dsn.
            return _super.prototype._setupTransport.call(this);
        }
        var dsn = new Dsn(this._options.dsn);
        var transportOptions = __assign(__assign(__assign(__assign(__assign({}, this._options.transportOptions), (this._options.httpProxy && { httpProxy: this._options.httpProxy })), (this._options.httpsProxy && { httpsProxy: this._options.httpsProxy })), (this._options.caCerts && { caCerts: this._options.caCerts })), { dsn: this._options.dsn });
        if (this._options.transport) {
            return new this._options.transport(transportOptions);
        }
        if (dsn.protocol === 'http') {
            return new HTTPTransport(transportOptions);
        }
        return new HTTPSTransport(transportOptions);
    };
    return NodeBackend;
}(BaseBackend));
export { NodeBackend };
//# sourceMappingURL=backend.js.map