mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
125 lines
3.9 KiB
TypeScript
125 lines
3.9 KiB
TypeScript
import type {Config} from 'sentry/types';
|
|
import {extractSlug} from 'sentry/utils/extractSlug';
|
|
|
|
const BOOTSTRAP_URL = '/api/client-config/';
|
|
|
|
const bootApplication = (data: Config) => {
|
|
window.csrfCookieName = data.csrfCookieName;
|
|
window.superUserCookieName = data.superUserCookieName;
|
|
window.superUserCookieDomain = data.superUserCookieDomain ?? undefined;
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Load the client configuration data using the BOOTSTRAP_URL. Used when
|
|
* running in standalone SPA mode.
|
|
*/
|
|
async function bootWithHydration() {
|
|
const response = await fetch(BOOTSTRAP_URL);
|
|
const data: Config = await response.json();
|
|
|
|
// Shim up the initialData payload to quack like it came from
|
|
// a customer-domains initial request. Because our initial call to BOOTSTRAP_URL
|
|
// will not be on a customer domain, the response will not include this context.
|
|
if (data.customerDomain === null && window.__SENTRY_DEV_UI) {
|
|
const domain = extractSlug(window.location.host);
|
|
if (domain) {
|
|
data.customerDomain = {
|
|
organizationUrl: `https://${domain.slug}.sentry.io`,
|
|
sentryUrl: 'https://sentry.io',
|
|
subdomain: domain.slug,
|
|
};
|
|
}
|
|
}
|
|
window.__initialData = data;
|
|
|
|
bootApplication(data);
|
|
preloadOrganizationData(data);
|
|
|
|
return data;
|
|
}
|
|
|
|
function promiseRequest(url: string): Promise<any> {
|
|
return new Promise(function (resolve, reject) {
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url);
|
|
xhr.setRequestHeader('sentry-trace', window.__initialData.initialTrace.sentry_trace);
|
|
xhr.setRequestHeader('baggage', window.__initialData.initialTrace.baggage);
|
|
xhr.withCredentials = true;
|
|
xhr.onload = function () {
|
|
try {
|
|
this.status >= 200 && this.status < 300
|
|
? resolve([JSON.parse(xhr.response), this.statusText, xhr])
|
|
: reject([this.status, this.statusText]);
|
|
} catch (e) {
|
|
reject();
|
|
}
|
|
};
|
|
xhr.onerror = function () {
|
|
reject([this.status, this.statusText]);
|
|
};
|
|
xhr.send();
|
|
});
|
|
}
|
|
|
|
function preloadOrganizationData(config: Config) {
|
|
if (!config.user) {
|
|
// Don't send requests if there is no logged in user.
|
|
return;
|
|
}
|
|
let slug = config.lastOrganization;
|
|
if (!slug && config.customerDomain) {
|
|
slug = config.customerDomain.subdomain;
|
|
}
|
|
|
|
let host = '';
|
|
if (config.links?.regionUrl && config.links?.regionUrl !== config.links?.sentryUrl) {
|
|
host = config.links.regionUrl;
|
|
}
|
|
// When running in 'dev-ui' mode we need to use /region/$region instead of
|
|
// subdomains so that webpack/vercel can proxy requests.
|
|
if (host && window.__SENTRY_DEV_UI) {
|
|
const domainpattern = /https?\:\/\/([^.]*)\.sentry.io/;
|
|
const domainmatch = host.match(domainpattern);
|
|
if (domainmatch) {
|
|
host = `/region/${domainmatch[1]}`;
|
|
}
|
|
}
|
|
|
|
function makeUrl(suffix: string) {
|
|
return host + '/api/0/organizations/' + slug + suffix;
|
|
}
|
|
|
|
const preloadPromises: Record<string, any> = {orgSlug: slug};
|
|
window.__sentry_preload = preloadPromises;
|
|
try {
|
|
preloadPromises.organization = promiseRequest(makeUrl('/?detailed=0'));
|
|
preloadPromises.projects = promiseRequest(
|
|
makeUrl('/projects/?all_projects=1&collapse=latestDeploys')
|
|
);
|
|
preloadPromises.teams = promiseRequest(makeUrl('/teams/'));
|
|
} catch (e) {
|
|
// eslint-disable-next-line
|
|
console.error(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load client configuration bootstrap data. This will detect if the app is
|
|
* running in SPA mode or being booted from the django-rendered layout.html
|
|
* template.
|
|
*/
|
|
export async function bootstrap() {
|
|
const bootstrapData = window.__initialData;
|
|
|
|
// If __initialData is not already set on the window, we are likely running in
|
|
// pure SPA mode, meaning django is not serving our frontend application and we
|
|
// need to make an API request to hydrate the bootstrap data to boot the app.
|
|
if (bootstrapData === undefined) {
|
|
return await bootWithHydration();
|
|
}
|
|
|
|
return bootApplication(bootstrapData);
|
|
}
|