@sentry/wizard
Version:
Sentry wizard helping you to configure your project
291 lines (290 loc) • 12.9 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports._enableTracingAndInstrumentationInConfig = exports.enableTracingAndInstrumentation = exports.loadSvelteConfig = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const url = __importStar(require("url"));
const chalk_1 = __importDefault(require("chalk"));
const Sentry = __importStar(require("@sentry/node"));
const recast = __importStar(require("recast"));
//@ts-expect-error - clack is ESM and TS complains about that. It works though
const prompts_1 = __importDefault(require("@clack/prompts"));
const clack_1 = require("../../utils/clack");
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
const magicast_1 = require("magicast");
const debug_1 = require("../../utils/debug");
const SVELTE_CONFIG_FILE = 'svelte.config.js';
const b = recast.types.builders;
async function loadSvelteConfig() {
const configFilePath = path.join(process.cwd(), SVELTE_CONFIG_FILE);
try {
if (!fs.existsSync(configFilePath)) {
return {};
}
const configUrl = url.pathToFileURL(configFilePath).href;
const svelteConfigModule = (await import(configUrl));
return svelteConfigModule?.default || {};
}
catch (e) {
prompts_1.default.log.error(`Couldn't load ${chalk_1.default.cyan(SVELTE_CONFIG_FILE)}.
Are you running this wizard from the root of your SvelteKit project?`);
prompts_1.default.log.info(chalk_1.default.dim(typeof e === 'object' && e != null && 'toString' in e
? e.toString()
: typeof e === 'string'
? e
: 'Unknown error'));
return {};
}
}
exports.loadSvelteConfig = loadSvelteConfig;
async function enableTracingAndInstrumentation(originalSvelteConfig, enableTracing) {
const hasTracingEnabled = originalSvelteConfig.kit?.experimental?.tracing;
const hasInstrumentationEnabled = originalSvelteConfig.kit?.experimental?.instrumentation;
if (hasTracingEnabled && hasInstrumentationEnabled) {
prompts_1.default.log.info('Tracing and instrumentation are already enabled.');
return;
}
if (hasTracingEnabled || hasInstrumentationEnabled) {
prompts_1.default.log.info('Tracing and instrumentation are partially enabled. Make sure both options are enabled.');
await showFallbackConfigSnippet();
return;
}
else {
try {
const configPath = path.join(process.cwd(), SVELTE_CONFIG_FILE);
const svelteConfigContent = await fs.promises.readFile(configPath, 'utf-8');
const { error, result } = _enableTracingAndInstrumentationInConfig(svelteConfigContent, enableTracing);
if (error) {
prompts_1.default.log.warning('Failed to automatically enable SvelteKit tracing and instrumentation.');
(0, debug_1.debug)(error);
Sentry.captureException(error);
await showFallbackConfigSnippet();
return;
}
if (result) {
await fs.promises.writeFile(configPath, result);
}
prompts_1.default.log.success(`Enabled tracing and instrumentation in ${chalk_1.default.cyan(SVELTE_CONFIG_FILE)}`);
}
catch (e) {
prompts_1.default.log.error(`Failed to enable tracing and instrumentation in ${chalk_1.default.cyan(SVELTE_CONFIG_FILE)}.`);
(0, debug_1.debug)(e);
Sentry.captureException(`Failed to enable tracing and instrumentation in ${SVELTE_CONFIG_FILE}`);
await showFallbackConfigSnippet();
return;
}
}
}
exports.enableTracingAndInstrumentation = enableTracingAndInstrumentation;
function _enableTracingAndInstrumentationInConfig(config, enableTracing) {
let svelteConfig;
try {
svelteConfig = (0, magicast_1.parseModule)(config);
}
catch (e) {
return {
error: 'Failed to parse Svelte config',
};
}
let configObject = undefined;
// Cases to handle for finding the config object:
// 1. default export is named object
// 2. default export is in-place object
// 3. default export is an identifier, so look up the variable declaration
recast.visit(svelteConfig.$ast, {
visitExportDefaultDeclaration(path) {
const exportDeclarationNode = path.node;
if (exportDeclarationNode.declaration.type === 'AssignmentExpression' &&
exportDeclarationNode.declaration.right.type === 'ObjectExpression') {
configObject = exportDeclarationNode.declaration.right;
return false;
}
if (exportDeclarationNode.declaration.type === 'ObjectExpression') {
configObject = exportDeclarationNode.declaration;
return false;
}
if (exportDeclarationNode.declaration.type === 'Identifier') {
const identifierName = exportDeclarationNode.declaration.name;
recast.visit(svelteConfig.$ast, {
visitVariableDeclarator(path) {
if (path.node.id?.type === 'Identifier' &&
path.node.id.name === identifierName &&
path.node.init?.type === 'ObjectExpression') {
configObject = path.node.init;
return false;
}
this.traverse(path);
},
});
}
this.traverse(path);
},
});
if (!_isValidConfigObject(configObject)) {
return {
error: "Couldn't find the config object",
};
}
// This type cast is safe. For some reason, TS still assumes that `configObject`
// is `undefined` so we have to tell it that it's not (see check above)
const validatedConfigObject = configObject;
const kitProp = validatedConfigObject.properties.find((prop) => prop.type === 'ObjectProperty' &&
prop.key.type === 'Identifier' &&
prop.key.name === 'kit');
if (!kitProp || kitProp.type !== 'ObjectProperty') {
return {
error: "Couldn't find the `kit` property",
};
}
if (kitProp.value.type !== 'ObjectExpression') {
return {
error: `\`kit\` property has unexpected type: ${kitProp.value.type}`,
};
}
// 1. find or add `kit.experimental` property
// type-cast because TS can't infer the type in `.find` :(
const kitExperimentalProp = kitProp.value.properties.find((prop) => prop.type === 'ObjectProperty' &&
prop.key.type === 'Identifier' &&
prop.key.name === 'experimental');
let experimentalObject;
if (kitExperimentalProp) {
if (kitExperimentalProp.value.type !== 'ObjectExpression') {
return {
error: `Property \`kit.experimental\` has unexpected type: ${kitExperimentalProp.value.type}`,
};
}
experimentalObject = kitExperimentalProp.value;
}
else {
experimentalObject = b.objectExpression([]);
kitProp.value.properties.push(b.objectProperty(b.identifier('experimental'), experimentalObject));
}
// 2. find or add `kit.experimental.tracing` property
// find or add `kit.experimental.instrumentation` property
const kitExperimentalTraingProp = experimentalObject.properties.find((prop) => prop.type === 'ObjectProperty' &&
prop.key.type === 'Identifier' &&
prop.key.name === 'tracing');
const kitExperimentalInstrumentationProp = experimentalObject.properties.find((prop) => prop.type === 'ObjectProperty' &&
prop.key.type === 'Identifier' &&
prop.key.name === 'instrumentation');
let experimentalTracingObject;
let experimentalInstrumentationObject;
if (kitExperimentalTraingProp) {
if (kitExperimentalTraingProp.value.type !== 'ObjectExpression') {
return {
error: `Property \`kit.experimental.tracing\` has unexpected type: ${kitExperimentalTraingProp.value.type}`,
};
}
experimentalTracingObject = kitExperimentalTraingProp.value;
}
else {
experimentalTracingObject = b.objectExpression([]);
experimentalObject.properties.push(b.objectProperty(b.identifier('tracing'), experimentalTracingObject));
}
if (kitExperimentalInstrumentationProp) {
if (kitExperimentalInstrumentationProp.value.type !== 'ObjectExpression') {
return {
error: `Property \`kit.experimental.instrumentation\` has unexpected type: ${kitExperimentalInstrumentationProp.value.type}`,
};
}
experimentalInstrumentationObject =
kitExperimentalInstrumentationProp.value;
}
else {
experimentalInstrumentationObject = b.objectExpression([]);
experimentalObject.properties.push(b.objectProperty(b.identifier('instrumentation'), experimentalInstrumentationObject));
}
// 3. find or add `kit.experimental.tracing.server` property
// find or add `kit.experimental.instrumentation.server` property
const kitExperimentalTracingSeverProp = experimentalTracingObject.properties.find((prop) => prop.type === 'ObjectProperty' &&
prop.key.type === 'Identifier' &&
prop.key.name === 'server');
const kitExperimentalInstrumentationSeverProp = experimentalInstrumentationObject.properties.find((prop) => prop.type === 'ObjectProperty' &&
prop.key.type === 'Identifier' &&
prop.key.name === 'server');
if (kitExperimentalTracingSeverProp) {
if (kitExperimentalTracingSeverProp.value.type !== 'BooleanLiteral') {
return {
error: `Property \`kit.experimental.tracing.server\` has unexpected type: ${kitExperimentalTracingSeverProp.value.type}`,
};
}
kitExperimentalTracingSeverProp.value = b.booleanLiteral(enableTracing);
}
else {
experimentalTracingObject.properties.push(b.objectProperty(b.identifier('server'), b.booleanLiteral(enableTracing)));
}
if (kitExperimentalInstrumentationSeverProp) {
if (kitExperimentalInstrumentationSeverProp.value.type !== 'BooleanLiteral') {
return {
error: `Property \`kit.experimental.instrumentation.server\` has unexpected type: ${kitExperimentalInstrumentationSeverProp.value.type}`,
};
}
kitExperimentalInstrumentationSeverProp.value = b.booleanLiteral(true);
}
else {
experimentalInstrumentationObject.properties.push(b.objectProperty(b.identifier('server'), b.booleanLiteral(true)));
}
try {
return {
result: (0, magicast_1.generateCode)(svelteConfig).code,
};
}
catch (e) {
(0, debug_1.debug)(e);
return {
error: 'Failed to generate code for Svelte config',
};
}
}
exports._enableTracingAndInstrumentationInConfig = _enableTracingAndInstrumentationInConfig;
function _isValidConfigObject(o) {
return !!o && o.type === 'ObjectExpression';
}
async function showFallbackConfigSnippet() {
const codeSnippet = (0, clack_1.makeCodeSnippet)(true, (unchanged, plus) => unchanged(`const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter(),
${plus(`experimental: {
instrumentation: {
server: true,
},
tracing: {
server: true,
},
},`)}
},
};
`));
await (0, clack_1.showCopyPasteInstructions)({
filename: 'svelte.config.js',
codeSnippet,
});
}
//# sourceMappingURL=svelte-config.js.map