UNPKG

next-video

Version:

A React component for adding video to your Next.js application. It extends both the video element and your Next app with features for automatic video optimization.

86 lines (84 loc) 2.99 kB
import { builders, parseModule, loadFile, generateCode, writeFile } from "magicast"; import fs from "node:fs/promises"; import path from "node:path"; import { PACKAGE_NAME } from "../../constants.js"; import { videoConfigDefault } from "../../config.js"; function extensionToType(filePath) { if (filePath.endsWith(".mjs") || filePath.endsWith(".ts")) { return "module"; } return "commonjs"; } async function updateNextConfigFile(parentDir = "./", videoConfig) { let type = "commonjs"; let configPath = void 0; let configContents = ""; const pathsToCheck = ["next.config.js", "next.config.mjs", "next.config.ts"]; for (let i = 0; i < pathsToCheck.length; i++) { const filePath = path.join(parentDir, pathsToCheck[i]); let exists; try { exists = await fs.stat(filePath); } catch (e) { exists = false; } if (exists) { type = extensionToType(pathsToCheck[i]); configPath = filePath; configContents = await fs.readFile(filePath, "utf-8"); break; } } if (!configPath) { throw { error: "not_found" }; } if (configContents.includes(PACKAGE_NAME)) { throw { error: "already_added" }; } if (type === "commonjs") { const mod = parseModule(configContents); const body = mod?.$ast?.body; let i = body.length ?? 0; while (i--) { const node = body[i]; if (node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression") { const { left, right } = node.expression ?? {}; if (left.type === "MemberExpression" && left.object.type === "Identifier" && left.object.name === "module") { if (left.property.type === "Identifier" && left.property.name === "exports") { if (right.type === "Identifier") { const expressionToWrap = generateCode(right).code; node.expression.right = wrapWithNextVideo(expressionToWrap, videoConfig).$ast; } } } } } let code = `const { withNextVideo } = require('${path.posix.join(PACKAGE_NAME, "process")}') ${generateCode(mod).code} `; await fs.writeFile(configPath, code); return { type, configPath }; } if (type === "module") { const mod = await loadFile(configPath); mod.imports.$add({ from: path.posix.join(PACKAGE_NAME, "process"), imported: "withNextVideo", local: "withNextVideo" }); const expressionToWrap = generateCode(mod.exports.default.$ast).code; mod.exports.default = wrapWithNextVideo(expressionToWrap, videoConfig); writeFile(mod, configPath); return { type, configPath }; } } function wrapWithNextVideo(expressionToWrap, videoConfig) { if (videoConfig?.folder && videoConfig.folder !== videoConfigDefault.folder) { return builders.raw(`withNextVideo(${expressionToWrap}, { folder: '${videoConfig.folder}' })`); } else { return builders.raw(`withNextVideo(${expressionToWrap})`); } } export { updateNextConfigFile as default };