@botport/core
Version:
Unified framework for Discord bot products, published by BotPort. Combines docky and framework functionality.
156 lines (131 loc) • 4.08 kB
JavaScript
import { fileURLToPath } from 'url';
import path from 'path';
import fs from 'fs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* Find the user's project root when running as an installed npm package
* This file will be in node_modules/@botport/tickets/lib/utils/pathResolver.js
* We need to go UP to find the actual project using this package
*/
function findProjectRoot(startPath = __dirname) {
let currentPath = startPath;
const root = path.parse(currentPath).root;
// If we're in node_modules, go up until we're OUT of node_modules
while (currentPath !== root) {
// Check if we're inside node_modules
if (currentPath.includes('node_modules')) {
// Keep going up
currentPath = path.dirname(currentPath);
continue;
}
// Now we're outside node_modules, check if this is a valid project root
const packageJsonPath = path.join(currentPath, 'package.json');
if (fs.existsSync(packageJsonPath)) {
// This should be the user's project!
return currentPath;
}
currentPath = path.dirname(currentPath);
}
// Fallback: use process.cwd() which should be the user's project directory
return process.cwd();
}
/**
* Cached project root
*/
let _projectRoot = null;
export function getProjectRoot() {
if (!_projectRoot) {
_projectRoot = findProjectRoot();
}
return _projectRoot;
}
/**
* Resolve paths relative to project root
*/
export function resolveProjectPath(...segments) {
return path.join(getProjectRoot(), ...segments);
}
/**
* Find the src directory (handles both dev and production)
*/
export function getSrcDir() {
const root = getProjectRoot();
const srcPath = path.join(root, 'src');
if (fs.existsSync(srcPath)) {
return srcPath;
}
// Fallback if src doesn't exist
return root;
}
/**
* Get config directory path
*/
export function getConfigDir() {
return resolveProjectPath('src', 'config');
}
/**
* Get .env file path
*/
export function getEnvPath() {
const root = getProjectRoot();
// Try multiple possible locations for .env
const possiblePaths = [
path.join(root, 'src', 'config', '.env'), // Standard location
path.join(root, 'config', '.env'), // Alternative
path.join(root, '.env'), // Root level
];
for (const envPath of possiblePaths) {
if (fs.existsSync(envPath)) {
return envPath;
}
}
// Return the standard location even if it doesn't exist
// (dotenv will handle the missing file gracefully)
return possiblePaths[0];
}
/**
* Get addons directory path
*/
export function getAddonsDir() {
return resolveProjectPath('src', 'addons');
}
/**
* Get events directory path
*/
export function getEventsDir() {
const root = getProjectRoot();
// Check if we're running from node_modules (installed package)
if (__dirname.includes('node_modules')) {
// Look for events in the USER'S project, not the package
const userEventsPath = path.join(root, 'lib', 'events');
if (fs.existsSync(userEventsPath)) {
return userEventsPath;
}
// Fallback: maybe events are in src?
const srcEventsPath = path.join(root, 'src', 'events');
if (fs.existsSync(srcEventsPath)) {
return srcEventsPath;
}
}
// Development mode - events are in the framework's lib directory
return path.join(root, 'lib', 'events');
}
/**
* Get the framework's installation directory (where the npm package is)
*/
export function getFrameworkDir() {
// This file is at: node_modules/@botport/tickets/lib/utils/pathResolver.js
// Framework root is 2 levels up: node_modules/@botport/tickets
return path.resolve(__dirname, '..', '..');
}
export default {
getProjectRoot,
resolveProjectPath,
getSrcDir,
getConfigDir,
getEnvPath,
getAddonsDir,
getEventsDir,
getFrameworkDir
};