UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

137 lines (136 loc) 7.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.assertExtensionsConventions = assertExtensionsConventions; exports.assertExtensionsRequire = assertExtensionsRequire; const picocolors_1 = __importDefault(require("@brillout/picocolors")); const utils_js_1 = require("../../utils.js"); const resolveVikeConfigInternal_js_1 = require("../resolveVikeConfigInternal.js"); const node_path_1 = __importDefault(require("node:path")); const semver_1 = __importDefault(require("semver")); function assertExtensionsConventions(plusFile) { assertExtensionName(plusFile); assertConfigExportPath(plusFile); } function assertConfigExportPath(plusFile) { const { importPathAbsolute, filePathAbsoluteFilesystem } = plusFile.filePath; // Ejected Vike extension if (!importPathAbsolute) { const p = filePathAbsoluteFilesystem; (0, utils_js_1.assert)(!p.includes('node_modules')); return; } const name = getNameValue(plusFile); (0, utils_js_1.assert)(name); // already asserted in assertExtensionName() const importPathAbsoluteExpected = `${name}/config`; (0, utils_js_1.assertWarning)(importPathAbsolute === importPathAbsoluteExpected, `The Vike configuration of ${picocolors_1.default.bold(name)} is exported at ${picocolors_1.default.bold(importPathAbsolute)}, but it should be exported at ${picocolors_1.default.bold(importPathAbsoluteExpected)} instead.`, { onlyOnce: true }); } function assertExtensionName(plusFile) { const filePathToShowToUser = getFilePathToShowToUser(plusFile); const name = getNameValue(plusFile); (0, utils_js_1.assertUsage)(name, `Vike extension name missing: the config ${filePathToShowToUser} must define the setting ${picocolors_1.default.cyan('name')}`); } function assertExtensionsRequire(plusFiles) { const plusFilesRelevantList = plusFiles; // Collect extensions const extensions = {}; plusFilesRelevantList.forEach((plusFile) => { const name = getNameValue(plusFile); if (name) { const version = getExtensionVersion(name, plusFile); extensions[name] = version; } }); // Enforce `require` plusFilesRelevantList.forEach((plusFile) => { const require = resolveRequireSetting(plusFile); if (!require) return; const name = getNameValue(plusFile); const filePathToShowToUser = getFilePathToShowToUser(plusFile); (0, utils_js_1.assertUsage)(name, `Setting ${picocolors_1.default.bold('name')} is required for being able to use setting ${picocolors_1.default.bold('require')} in ${filePathToShowToUser}.`); Object.entries(require).forEach(([reqName, req]) => { const errBase = `${picocolors_1.default.bold(name)} requires ${picocolors_1.default.bold(reqName)}`; if (reqName === 'vike') { let errMsg = `${errBase} version ${picocolors_1.default.bold(req.version)}, but ${picocolors_1.default.bold(utils_js_1.PROJECT_VERSION)} is installed.`; if (req.optional) { errMsg += " Either update it, or remove it (it's an optional peer dependency)."; } (0, utils_js_1.assertUsage)(isVersionRange(utils_js_1.PROJECT_VERSION, req.version), errMsg); return; } const extensionVersion = extensions[reqName]; if (!extensionVersion) { if (req.optional) { return; } else { (0, utils_js_1.assertUsage)(false, `${errBase}.`); } } (0, utils_js_1.assertUsage)(isVersionRange(extensionVersion, req.version), `${errBase} version ${picocolors_1.default.bold(req.version)}, but ${picocolors_1.default.bold(extensionVersion)} is installed.`); }); }); } function resolveRequireSetting(plusFile) { const confVal = (0, resolveVikeConfigInternal_js_1.getConfVal)(plusFile, 'require'); if (!confVal) return null; (0, utils_js_1.assert)(confVal.valueIsLoaded); const requireValue = confVal.value; const { filePathToShowToUserResolved } = plusFile.filePath; (0, utils_js_1.assert)(filePathToShowToUserResolved); (0, utils_js_1.assertUsage)((0, utils_js_1.isObject)(requireValue), `The setting ${picocolors_1.default.bold('+require')} defined at ${filePathToShowToUserResolved} should be an object`); const requireSetting = {}; Object.entries(requireValue).forEach(([reqName, req]) => { if (typeof req === 'string') { requireSetting[reqName] = { version: req, optional: false }; return; } if ((0, utils_js_1.isObject)(req)) { requireSetting[reqName] = req; return; } (0, utils_js_1.assertUsage)(false, `Invalid +require[${JSON.stringify(reqName)}] value ${picocolors_1.default.cyan(JSON.stringify(req))}`); }); return requireSetting; } function getNameValue(plusFile) { const confVal = (0, resolveVikeConfigInternal_js_1.getConfVal)(plusFile, 'name'); if (!confVal) return null; (0, utils_js_1.assert)(confVal.valueIsLoaded); const name = confVal.value; const filePathToShowToUser = getFilePathToShowToUser(plusFile); (0, utils_js_1.assertUsage)(typeof name === 'string', `The setting ${picocolors_1.default.bold('name')} defined at ${filePathToShowToUser} should be a string.`); return name; } // We use a forever cache: users need to restart the dev server anyways when touching node_modules/**/* (I presume Vite doesn't pick up node_modules/**/* changes). const extensionsVersion = {}; function getExtensionVersion(name, plusFile) { if (!extensionsVersion[name]) { const extensionConfigFilePath = plusFile.filePath.filePathAbsoluteFilesystem; const found = (0, utils_js_1.findPackageJson)(node_path_1.default.posix.dirname(extensionConfigFilePath)); (0, utils_js_1.assert)(found); const { packageJson, packageJsonPath } = found; const filePathToShowToUser = getFilePathToShowToUser(plusFile); const nameExpected = packageJson.name; (0, utils_js_1.assertWarning)(name === nameExpected, `The setting ${picocolors_1.default.bold('name')} defined at ${filePathToShowToUser} is ${picocolors_1.default.bold(JSON.stringify(name))}, but it should be equal to ${picocolors_1.default.bold(JSON.stringify(nameExpected))} (the value of ${packageJsonPath}${picocolors_1.default.dim('#')}${picocolors_1.default.bold('name')})`, { onlyOnce: true }); const { version } = packageJson; (0, utils_js_1.assert)(typeof version === 'string'); extensionsVersion[name] = version; } return extensionsVersion[name]; } function getFilePathToShowToUser(plusFile) { const { filePathToShowToUserResolved } = plusFile.filePath; (0, utils_js_1.assert)(filePathToShowToUserResolved); return filePathToShowToUserResolved; } function isVersionRange(version, range) { // Remove pre-release tag version = version.split('-')[0]; return semver_1.default.satisfies(version, range); }