UNPKG

@sentry/wizard

Version:

Sentry wizard helping you to configure your project

291 lines (290 loc) 12.9 kB
"use strict"; 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