vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
137 lines (136 loc) • 7.3 kB
JavaScript
;
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);
}