-
Notifications
You must be signed in to change notification settings - Fork 90
Description
Is your feature request related to a problem?
Currently CLI modifies user's astro.config.ts
via AST transforms using Babel. This works really well but it quite heavy to maintain.
tutorialkit/packages/cli/src/utils/astro-config.ts
Lines 78 to 148 in 9333065
/** | |
* In the second pass, we search for a default export which is a call to `defineConfig` | |
* and we look for our `integrationId` that we just got from the `integrations` field. | |
*/ | |
visit(ast, { | |
ExportDefaultDeclaration(path) { | |
if (!t.isCallExpression(path.node.declaration)) { | |
return; | |
} | |
const configObject = path.node.declaration.arguments[0]; | |
if (!t.isObjectExpression(configObject)) { | |
throw new Error('TutorialKit is not part of the exported config'); | |
} | |
const integrationsProp = configObject.properties.find((prop) => { | |
if (prop.type !== 'ObjectProperty') { | |
return false; | |
} | |
if (prop.key.type === 'Identifier') { | |
if (prop.key.name === 'integrations') { | |
return true; | |
} | |
} | |
if (prop.key.type === 'StringLiteral') { | |
if (prop.key.value === 'integrations') { | |
return true; | |
} | |
} | |
return false; | |
}) as t.ObjectProperty | undefined; | |
if (integrationsProp.value.type !== 'ArrayExpression') { | |
throw new Error('Unable to parse integrations in Astro config'); | |
} | |
let integrationCall = integrationsProp.value.elements.find((expr) => { | |
return t.isCallExpression(expr) && t.isIdentifier(expr.callee) && expr.callee.name === integrationId.name; | |
}) as t.CallExpression | undefined; | |
// if the integration wasn't found we add it | |
if (!integrationCall) { | |
integrationCall = t.callExpression(integrationId, []); | |
integrationsProp.value.elements.push(integrationCall); | |
} | |
const integrationArgs = integrationCall.arguments; | |
// if `tutorialkit` is called as `tutorialkit()` | |
if (integrationArgs.length === 0) { | |
const objectArgs = fromValue(newTutorialKitArgs) as t.ObjectExpression; | |
if (objectArgs.properties.length > 0) { | |
integrationArgs.push(objectArgs); | |
} | |
return; | |
} | |
if (!t.isObjectExpression(integrationArgs[0])) { | |
throw new Error('Only updating an existing object literal as the config is supported'); | |
} | |
// if `tutorialkit` is called with an object literal we update its existing properties | |
updateObject(newTutorialKitArgs, integrationArgs[0]); | |
}, | |
}); |
Describe the solution you'd like.
Check if direct Babel usage could be replaced with magicast
. It provides much nicer API to work with AST transforms. This package is also used by Vitest, where we modify user's vitest.config.ts
. It's very similar to what TutorialKit does.
We should also add similar unit tests: https://github.com/vitest-dev/vitest/blob/main/test/coverage-test/test/threshold-auto-update.unit.test.ts
Describe alternatives you've considered.
Keep maintaining the direct Babel integration. It's reliable and does exactly what we need it to, but it's not as easy to maintain.
Additional context
No response