Add coexistence checks to all enqueue methods to prevent loading both React and Grid.js assets simultaneously. Changes: - ReactAdmin.php: Only enqueue React assets when ?react=1 - Init.php: Skip Grid.js when React active on admin pages - Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0 - Customer.php, Product.php, License.php: Add coexistence checks Now the toggle between Classic and React versions works correctly. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
441 lines
15 KiB
JavaScript
441 lines
15 KiB
JavaScript
import { __assign, __read, __spread } from "tslib";
|
|
import { dateTimestampInSeconds, getGlobalSingleton, isPlainObject, isThenable, SyncPromise } from '@sentry/utils';
|
|
/**
|
|
* Absolute maximum number of breadcrumbs added to an event.
|
|
* The `maxBreadcrumbs` option cannot be higher than this value.
|
|
*/
|
|
var MAX_BREADCRUMBS = 100;
|
|
/**
|
|
* Holds additional event information. {@link Scope.applyToEvent} will be
|
|
* called by the client before an event will be sent.
|
|
*/
|
|
var Scope = /** @class */ (function () {
|
|
function Scope() {
|
|
/** Flag if notifying is happening. */
|
|
this._notifyingListeners = false;
|
|
/** Callback for client to receive scope changes. */
|
|
this._scopeListeners = [];
|
|
/** Callback list that will be called after {@link applyToEvent}. */
|
|
this._eventProcessors = [];
|
|
/** Array of breadcrumbs. */
|
|
this._breadcrumbs = [];
|
|
/** User */
|
|
this._user = {};
|
|
/** Tags */
|
|
this._tags = {};
|
|
/** Extra */
|
|
this._extra = {};
|
|
/** Contexts */
|
|
this._contexts = {};
|
|
/**
|
|
* A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
|
|
* sent to Sentry
|
|
*/
|
|
this._sdkProcessingMetadata = {};
|
|
}
|
|
/**
|
|
* Inherit values from the parent scope.
|
|
* @param scope to clone.
|
|
*/
|
|
Scope.clone = function (scope) {
|
|
var newScope = new Scope();
|
|
if (scope) {
|
|
newScope._breadcrumbs = __spread(scope._breadcrumbs);
|
|
newScope._tags = __assign({}, scope._tags);
|
|
newScope._extra = __assign({}, scope._extra);
|
|
newScope._contexts = __assign({}, scope._contexts);
|
|
newScope._user = scope._user;
|
|
newScope._level = scope._level;
|
|
newScope._span = scope._span;
|
|
newScope._session = scope._session;
|
|
newScope._transactionName = scope._transactionName;
|
|
newScope._fingerprint = scope._fingerprint;
|
|
newScope._eventProcessors = __spread(scope._eventProcessors);
|
|
newScope._requestSession = scope._requestSession;
|
|
}
|
|
return newScope;
|
|
};
|
|
/**
|
|
* Add internal on change listener. Used for sub SDKs that need to store the scope.
|
|
* @hidden
|
|
*/
|
|
Scope.prototype.addScopeListener = function (callback) {
|
|
this._scopeListeners.push(callback);
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.addEventProcessor = function (callback) {
|
|
this._eventProcessors.push(callback);
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setUser = function (user) {
|
|
this._user = user || {};
|
|
if (this._session) {
|
|
this._session.update({ user: user });
|
|
}
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.getUser = function () {
|
|
return this._user;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.getRequestSession = function () {
|
|
return this._requestSession;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setRequestSession = function (requestSession) {
|
|
this._requestSession = requestSession;
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setTags = function (tags) {
|
|
this._tags = __assign(__assign({}, this._tags), tags);
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setTag = function (key, value) {
|
|
var _a;
|
|
this._tags = __assign(__assign({}, this._tags), (_a = {}, _a[key] = value, _a));
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setExtras = function (extras) {
|
|
this._extra = __assign(__assign({}, this._extra), extras);
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setExtra = function (key, extra) {
|
|
var _a;
|
|
this._extra = __assign(__assign({}, this._extra), (_a = {}, _a[key] = extra, _a));
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setFingerprint = function (fingerprint) {
|
|
this._fingerprint = fingerprint;
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setLevel = function (level) {
|
|
this._level = level;
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setTransactionName = function (name) {
|
|
this._transactionName = name;
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* Can be removed in major version.
|
|
* @deprecated in favor of {@link this.setTransactionName}
|
|
*/
|
|
Scope.prototype.setTransaction = function (name) {
|
|
return this.setTransactionName(name);
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setContext = function (key, context) {
|
|
var _a;
|
|
if (context === null) {
|
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
delete this._contexts[key];
|
|
}
|
|
else {
|
|
this._contexts = __assign(__assign({}, this._contexts), (_a = {}, _a[key] = context, _a));
|
|
}
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setSpan = function (span) {
|
|
this._span = span;
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.getSpan = function () {
|
|
return this._span;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.getTransaction = function () {
|
|
// Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will
|
|
// have a pointer to the currently-active transaction.
|
|
var span = this.getSpan();
|
|
return span && span.transaction;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.setSession = function (session) {
|
|
if (!session) {
|
|
delete this._session;
|
|
}
|
|
else {
|
|
this._session = session;
|
|
}
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.getSession = function () {
|
|
return this._session;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.update = function (captureContext) {
|
|
if (!captureContext) {
|
|
return this;
|
|
}
|
|
if (typeof captureContext === 'function') {
|
|
var updatedScope = captureContext(this);
|
|
return updatedScope instanceof Scope ? updatedScope : this;
|
|
}
|
|
if (captureContext instanceof Scope) {
|
|
this._tags = __assign(__assign({}, this._tags), captureContext._tags);
|
|
this._extra = __assign(__assign({}, this._extra), captureContext._extra);
|
|
this._contexts = __assign(__assign({}, this._contexts), captureContext._contexts);
|
|
if (captureContext._user && Object.keys(captureContext._user).length) {
|
|
this._user = captureContext._user;
|
|
}
|
|
if (captureContext._level) {
|
|
this._level = captureContext._level;
|
|
}
|
|
if (captureContext._fingerprint) {
|
|
this._fingerprint = captureContext._fingerprint;
|
|
}
|
|
if (captureContext._requestSession) {
|
|
this._requestSession = captureContext._requestSession;
|
|
}
|
|
}
|
|
else if (isPlainObject(captureContext)) {
|
|
// eslint-disable-next-line no-param-reassign
|
|
captureContext = captureContext;
|
|
this._tags = __assign(__assign({}, this._tags), captureContext.tags);
|
|
this._extra = __assign(__assign({}, this._extra), captureContext.extra);
|
|
this._contexts = __assign(__assign({}, this._contexts), captureContext.contexts);
|
|
if (captureContext.user) {
|
|
this._user = captureContext.user;
|
|
}
|
|
if (captureContext.level) {
|
|
this._level = captureContext.level;
|
|
}
|
|
if (captureContext.fingerprint) {
|
|
this._fingerprint = captureContext.fingerprint;
|
|
}
|
|
if (captureContext.requestSession) {
|
|
this._requestSession = captureContext.requestSession;
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.clear = function () {
|
|
this._breadcrumbs = [];
|
|
this._tags = {};
|
|
this._extra = {};
|
|
this._user = {};
|
|
this._contexts = {};
|
|
this._level = undefined;
|
|
this._transactionName = undefined;
|
|
this._fingerprint = undefined;
|
|
this._requestSession = undefined;
|
|
this._span = undefined;
|
|
this._session = undefined;
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.addBreadcrumb = function (breadcrumb, maxBreadcrumbs) {
|
|
var maxCrumbs = typeof maxBreadcrumbs === 'number' ? Math.min(maxBreadcrumbs, MAX_BREADCRUMBS) : MAX_BREADCRUMBS;
|
|
// No data has been changed, so don't notify scope listeners
|
|
if (maxCrumbs <= 0) {
|
|
return this;
|
|
}
|
|
var mergedBreadcrumb = __assign({ timestamp: dateTimestampInSeconds() }, breadcrumb);
|
|
this._breadcrumbs = __spread(this._breadcrumbs, [mergedBreadcrumb]).slice(-maxCrumbs);
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Scope.prototype.clearBreadcrumbs = function () {
|
|
this._breadcrumbs = [];
|
|
this._notifyScopeListeners();
|
|
return this;
|
|
};
|
|
/**
|
|
* Applies the current context and fingerprint to the event.
|
|
* Note that breadcrumbs will be added by the client.
|
|
* Also if the event has already breadcrumbs on it, we do not merge them.
|
|
* @param event Event
|
|
* @param hint May contain additional information about the original exception.
|
|
* @hidden
|
|
*/
|
|
Scope.prototype.applyToEvent = function (event, hint) {
|
|
if (this._extra && Object.keys(this._extra).length) {
|
|
event.extra = __assign(__assign({}, this._extra), event.extra);
|
|
}
|
|
if (this._tags && Object.keys(this._tags).length) {
|
|
event.tags = __assign(__assign({}, this._tags), event.tags);
|
|
}
|
|
if (this._user && Object.keys(this._user).length) {
|
|
event.user = __assign(__assign({}, this._user), event.user);
|
|
}
|
|
if (this._contexts && Object.keys(this._contexts).length) {
|
|
event.contexts = __assign(__assign({}, this._contexts), event.contexts);
|
|
}
|
|
if (this._level) {
|
|
event.level = this._level;
|
|
}
|
|
if (this._transactionName) {
|
|
event.transaction = this._transactionName;
|
|
}
|
|
// We want to set the trace context for normal events only if there isn't already
|
|
// a trace context on the event. There is a product feature in place where we link
|
|
// errors with transaction and it relies on that.
|
|
if (this._span) {
|
|
event.contexts = __assign({ trace: this._span.getTraceContext() }, event.contexts);
|
|
var transactionName = this._span.transaction && this._span.transaction.name;
|
|
if (transactionName) {
|
|
event.tags = __assign({ transaction: transactionName }, event.tags);
|
|
}
|
|
}
|
|
this._applyFingerprint(event);
|
|
event.breadcrumbs = __spread((event.breadcrumbs || []), this._breadcrumbs);
|
|
event.breadcrumbs = event.breadcrumbs.length > 0 ? event.breadcrumbs : undefined;
|
|
event.sdkProcessingMetadata = this._sdkProcessingMetadata;
|
|
return this._notifyEventProcessors(__spread(getGlobalEventProcessors(), this._eventProcessors), event, hint);
|
|
};
|
|
/**
|
|
* Add data which will be accessible during event processing but won't get sent to Sentry
|
|
*/
|
|
Scope.prototype.setSDKProcessingMetadata = function (newData) {
|
|
this._sdkProcessingMetadata = __assign(__assign({}, this._sdkProcessingMetadata), newData);
|
|
return this;
|
|
};
|
|
/**
|
|
* This will be called after {@link applyToEvent} is finished.
|
|
*/
|
|
Scope.prototype._notifyEventProcessors = function (processors, event, hint, index) {
|
|
var _this = this;
|
|
if (index === void 0) { index = 0; }
|
|
return new SyncPromise(function (resolve, reject) {
|
|
var processor = processors[index];
|
|
if (event === null || typeof processor !== 'function') {
|
|
resolve(event);
|
|
}
|
|
else {
|
|
var result = processor(__assign({}, event), hint);
|
|
if (isThenable(result)) {
|
|
void result
|
|
.then(function (final) { return _this._notifyEventProcessors(processors, final, hint, index + 1).then(resolve); })
|
|
.then(null, reject);
|
|
}
|
|
else {
|
|
void _this._notifyEventProcessors(processors, result, hint, index + 1)
|
|
.then(resolve)
|
|
.then(null, reject);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
/**
|
|
* This will be called on every set call.
|
|
*/
|
|
Scope.prototype._notifyScopeListeners = function () {
|
|
var _this = this;
|
|
// We need this check for this._notifyingListeners to be able to work on scope during updates
|
|
// If this check is not here we'll produce endless recursion when something is done with the scope
|
|
// during the callback.
|
|
if (!this._notifyingListeners) {
|
|
this._notifyingListeners = true;
|
|
this._scopeListeners.forEach(function (callback) {
|
|
callback(_this);
|
|
});
|
|
this._notifyingListeners = false;
|
|
}
|
|
};
|
|
/**
|
|
* Applies fingerprint from the scope to the event if there's one,
|
|
* uses message if there's one instead or get rid of empty fingerprint
|
|
*/
|
|
Scope.prototype._applyFingerprint = function (event) {
|
|
// Make sure it's an array first and we actually have something in place
|
|
event.fingerprint = event.fingerprint
|
|
? Array.isArray(event.fingerprint)
|
|
? event.fingerprint
|
|
: [event.fingerprint]
|
|
: [];
|
|
// If we have something on the scope, then merge it with event
|
|
if (this._fingerprint) {
|
|
event.fingerprint = event.fingerprint.concat(this._fingerprint);
|
|
}
|
|
// If we have no data at all, remove empty array default
|
|
if (event.fingerprint && !event.fingerprint.length) {
|
|
delete event.fingerprint;
|
|
}
|
|
};
|
|
return Scope;
|
|
}());
|
|
export { Scope };
|
|
/**
|
|
* Returns the global event processors.
|
|
*/
|
|
function getGlobalEventProcessors() {
|
|
return getGlobalSingleton('globalEventProcessors', function () { return []; });
|
|
}
|
|
/**
|
|
* Add a EventProcessor to be kept globally.
|
|
* @param callback EventProcessor to add
|
|
*/
|
|
export function addGlobalEventProcessor(callback) {
|
|
getGlobalEventProcessors().push(callback);
|
|
}
|
|
//# sourceMappingURL=scope.js.map
|