storybook
Version:
Storybook: Develop, document, and test UI components in isolation
168 lines (163 loc) • 6.39 kB
JavaScript
import CJS_COMPAT_NODE_URL_qjinduibsyq from 'node:url';
import CJS_COMPAT_NODE_PATH_qjinduibsyq from 'node:path';
import CJS_COMPAT_NODE_MODULE_qjinduibsyq from "node:module";
var __filename = CJS_COMPAT_NODE_URL_qjinduibsyq.fileURLToPath(import.meta.url);
var __dirname = CJS_COMPAT_NODE_PATH_qjinduibsyq.dirname(__filename);
var require = CJS_COMPAT_NODE_MODULE_qjinduibsyq.createRequire(import.meta.url);
// ------------------------------------------------------------
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
// ------------------------------------------------------------
import {
StorybookError
} from "./chunk-DW727PJG.js";
// src/core-server/withTelemetry.ts
import {
HandledError,
cache,
loadMainConfig,
isCI,
loadAllPresets
} from "storybook/internal/common";
import { logger, prompt } from "storybook/internal/node-logger";
import {
ErrorCollector,
getPrecedingUpgrade,
isTelemetryStateResolved,
oneWayHash,
onPayloadError,
setTelemetryEnabled,
telemetry
} from "storybook/internal/telemetry";
var promptCrashReports = async () => {
if (isCI() || !process.stdout.isTTY)
return;
let enableCrashReports = await prompt.confirm({
message: "Would you like to send anonymous crash reports to improve Storybook and fix bugs faster?",
initialValue: !0
});
return await cache.set("enableCrashReports", enableCrashReports), enableCrashReports;
};
async function getErrorLevel({
cliOptions,
presetOptions,
skipPrompt,
eventType
}) {
if (cliOptions.disableTelemetry)
return "none";
if (!presetOptions && eventType !== "init")
return "error";
if (presetOptions) {
let core = await (await loadAllPresets(presetOptions)).apply("core");
if (core?.enableCrashReports !== void 0)
return core.enableCrashReports ? "full" : "error";
if (core?.disableTelemetry)
return "none";
}
let valueFromCache = await cache.get("enableCrashReports") ?? await cache.get("enableCrashreports");
if (valueFromCache !== void 0)
return valueFromCache ? "full" : "error";
if (skipPrompt)
return "error";
let valueFromPrompt = await promptCrashReports();
return valueFromPrompt !== void 0 ? valueFromPrompt ? "full" : "error" : "full";
}
async function sendTelemetryError(_error, eventType, options, blocking = !0, parent) {
try {
let errorLevel = "error";
try {
errorLevel = await getErrorLevel({
...options,
eventType,
skipPrompt: options.skipPrompt || eventType === "init" && !blocking
});
} catch {
}
if (errorLevel !== "none") {
let precedingUpgrade = await getPrecedingUpgrade(), error = _error, errorHash;
"message" in error ? errorHash = error.message ? oneWayHash(error.message) : "EMPTY_MESSAGE" : errorHash = "NO_MESSAGE";
let { code, name, category } = error;
if (await telemetry(
"error",
{
code,
name,
category,
eventType,
blocking,
precedingUpgrade,
error: errorLevel === "full" ? error : void 0,
errorHash,
// if we ever end up sending a non-error instance, we'd like to know
isErrorInstance: error instanceof Error,
// Include parent error information if this is a sub-error
...parent ? { parent: parent.fullErrorCode } : {}
},
{
immediate: !0,
configDir: options.cliOptions.configDir || options.presetOptions?.configDir,
enableCrashReports: errorLevel === "full",
force: !0
}
), error && "subErrors" in error && error.subErrors.length > 0)
for (let subError of error.subErrors)
await sendTelemetryError(subError, eventType, options, blocking, error);
}
} catch {
}
}
async function resolveTelemetryState(options) {
if (options.cliOptions.disableTelemetry !== void 0)
return await setTelemetryEnabled(!options.cliOptions.disableTelemetry);
let mainConfig, configDir = options.cliOptions.configDir ?? options.presetOptions?.configDir ?? ".storybook";
try {
mainConfig = await loadMainConfig({ configDir });
} catch {
}
if (mainConfig)
return await setTelemetryEnabled(!mainConfig?.core?.disableTelemetry);
await setTelemetryEnabled(options.fallbackTelemetryState ?? !1);
}
function isInterruptionError(error) {
if (!error || typeof error != "object")
return !1;
let signal = "signal" in error ? error.signal : void 0, code = "code" in error ? error.code : void 0, name = "name" in error ? error.name : void 0, message = "message" in error && typeof error.message == "string" ? error.message : void 0, cause = "cause" in error ? error.cause : void 0;
return signal === "SIGINT" || code === "ABORT_ERR" || code === "ERR_CANCELED" || name === "AbortError" || message?.includes("Command was killed with SIGINT") || message?.includes("The operation was aborted") || isInterruptionError(cause);
}
var CANCELLATION_TRACKED_EVENTS = ["init", "ai-command"];
async function withTelemetry(eventType, options, run) {
isTelemetryStateResolved() || await resolveTelemetryState(options);
let canceled = !1;
async function cancelTelemetry() {
canceled = !0, await telemetry("canceled", { eventType }, { stripMetadata: !0, immediate: !0 }), process.exit(0);
}
let trackCancellation = CANCELLATION_TRACKED_EVENTS.includes(eventType);
trackCancellation && process.on("SIGINT", cancelTelemetry), onPayloadError(async (error, evtType) => {
await sendTelemetryError(error, evtType, options);
}), telemetry("boot", { eventType }, { stripMetadata: !0 });
try {
return await run();
} catch (error) {
if (canceled)
return;
if (trackCancellation && isInterruptionError(error)) {
await cancelTelemetry();
return;
}
if (!(error instanceof HandledError || error instanceof StorybookError && error.isHandledError)) {
let { printError = logger.error } = options;
printError(error);
}
throw await sendTelemetryError(error, eventType, options), error;
} finally {
let errors = ErrorCollector.getErrors();
for (let error of errors)
await sendTelemetryError(error, eventType, options, !1);
process.off("SIGINT", cancelTelemetry), onPayloadError(void 0);
}
}
export {
getErrorLevel,
sendTelemetryError,
withTelemetry
};