Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | /**
* Utility functions for handling optional peer dependencies
*/
/**
* Check if a peer dependency is available
* @param {string} packageName - Name of the package to check
* @returns {boolean} - Whether the package is available
*/
export function isPeerDependencyAvailable(packageName) {
try {
// Try to import the package synchronously using require.resolve
// This is more compatible with code analysis tools
if (typeof require !== 'undefined' && require.resolve) {
require.resolve(packageName);
return true;
}
// Fallback: assume available if require is not available (browser context)
return false;
} catch {
return false;
}
}
/**
* Dynamically import a peer dependency with _error handling
* @param {string} packageName - Name of the package to import
* @param {string} integrationName - Human-readable name of the integration
* @returns {Promise<any>} - The imported module
* @throws {Error} - If the dependency is not available
*/
export async function importPeerDependency(packageName, integrationName) {
try {
return await import(packageName);
} catch {
throw new Error(
`${integrationName} integration requires the '${packageName}' package to be installed.\n` +
`Please install it with: npm install ${packageName}\n` +
`Or with pnpm: pnpm add ${packageName}\n` +
`Or with yarn: yarn add ${packageName}`
);
}
}
/**
* Create a lazy-loaded integration that only imports dependencies when needed
* @param {string} packageName - Name of the package to import
* @param {string} integrationName - Human-readable name of the integration
* @param {Function} createIntegration - Function that creates the integration using the imported package
* @returns {Function} - Lazy-loaded integration function
*/
export function createLazyIntegration(
packageName,
integrationName,
createIntegration
) {
let cachedIntegration = null;
let importPromise = null;
return async function (...args) {
// Return cached integration if available
if (cachedIntegration) {
return cachedIntegration(...args);
}
// Avoid multiple concurrent imports
if (!importPromise) {
importPromise = importPeerDependency(packageName, integrationName).then(
(module) => {
cachedIntegration = createIntegration(module);
return cachedIntegration;
}
);
}
const integration = await importPromise;
return integration(...args);
};
}
/**
* Check multiple peer dependencies and provide helpful _error messages
* @param {Array<{package: string, integration: string}>} dependencies - List of dependencies to check
* @returns {Object} - Object with availability status for each dependency
*/
export function checkPeerDependencies(dependencies) {
const results = {};
const missing = [];
for (const { package: packageName, integration } of dependencies) {
const available = isPeerDependencyAvailable(packageName);
results[packageName] = available;
if (!available) {
missing.push({ package: packageName, integration });
}
}
if (missing.length > 0) {
const installCommands = missing.map(({ package: pkg }) => pkg).join(' ');
const integrationsList = missing
.map(({ integration }) => integration)
.join(', ');
console.warn(
`Optional dependencies missing for ${integrationsList} integration(s).\n` +
`To use these integrations, install: npm install ${installCommands}\n` +
`Or with pnpm: pnpm add ${installCommands}\n` +
`Or with yarn: yarn add ${installCommands}`
);
}
return results;
}
/**
* Create a function that checks for a dependency before executing
* @param {string} packageName - Name of the package required
* @param {string} integrationName - Human-readable name of the integration
* @param {Function} fn - Function to execute if dependency is available
* @returns {Function} - Wrapped function with dependency check
*/
export function requirePeerDependency(packageName, integrationName, fn) {
return function (...args) {
if (!isPeerDependencyAvailable(packageName)) {
throw new Error(
`${integrationName} integration requires the '${packageName}' package to be installed.\n` +
`Please install it with: npm install ${packageName}`
);
}
return fn.apply(this, args);
};
}
|