123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import type {Config} from 'sentry/types/system';
- 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 {
- if (!slug) {
- return;
- }
- preloadPromises.organization = promiseRequest(
- makeUrl('/?detailed=0&include_feature_flags=1')
- );
- preloadPromises.projects = promiseRequest(
- makeUrl('/projects/?all_projects=1&collapse=latestDeploys&collapse=unusedFeatures')
- );
- 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);
- }
|