001-drive-proxy-adapter #1

Merged
Peter.Morton merged 25 commits from 001-drive-proxy-adapter into main 2026-03-07 12:45:57 -06:00
Showing only changes of commit 6450b93439 - Show all commits

View File

@@ -29,120 +29,71 @@ let globalVariableContext = {};
/** /**
* Load all files from globalVariables/ directory into globalVariableContext * Load all files from globalVariables/ directory into globalVariableContext
* Pattern: globalVariables/filename.{json|js} -> globalVariableContext['filename'] * Pattern: globalVariables/filename.{json|js} -> globalVariableContext['filename']
* - .json files: Parsed as JSON data
* - .js files: Executed via vm.Script, must return object via IIFE
*/ */
function loadGlobalVariables() { function loadGlobalVariables() {
const globalDir = join(__dirname, "globalVariables"); const globalDir = join(__dirname, "globalVariables");
const jsonFiles = [];
const jsFiles = [];
try { // Scan and categorize files in one pass
const allFiles = readdirSync(globalDir).filter( readdirSync(globalDir).forEach((file) => {
(f) => (f.endsWith(".json") || f.endsWith(".js")) && !f.endsWith(".example.json") && !f.endsWith(".example.js") if (file.includes(".example")) return;
); if (file.endsWith(".json")) jsonFiles.push(file);
else if (file.endsWith(".js")) jsFiles.push(file);
});
// Separate files by type // Load JSON files first (data)
const jsonFiles = allFiles.filter((f) => f.endsWith(".json")); jsonFiles.forEach((file) => {
const jsFiles = allFiles.filter((f) => f.endsWith(".js")); const varName = file.replace(".json", "");
const data = JSON.parse(readFileSync(join(globalDir, file), "utf-8"));
globalVariableContext[varName] = data;
logger.info(`Loaded global data: ${varName}`, { keys: Object.keys(data) });
});
// Load JSON files first (data) // Load JS files second (functions can reference JSON data)
jsonFiles.forEach((file) => { jsFiles.forEach((file) => {
const objectName = file.replace(".json", ""); const varName = file.replace(".js", "");
const filePath = join(globalDir, file); const code = readFileSync(join(globalDir, file), "utf-8");
const script = new vm.Script(code, { filename: file });
const context = vm.createContext({ ...globalVMContext, ...globalVariableContext });
globalVariableContext[varName] = script.runInContext(context);
logger.info(`Loaded global functions: ${varName}`);
});
try { logger.info(`Loaded ${jsonFiles.length + jsFiles.length} global variables`,
const content = readFileSync(filePath, "utf-8"); { json: jsonFiles.length, js: jsFiles.length }
const data = JSON.parse(content); );
globalVariableContext[objectName] = data;
logger.info(`Loaded global data: ${objectName}`, {
file: file,
keys: Object.keys(data),
});
} catch (error) {
logger.error(`Failed to load ${file}`, { error: error.message });
throw error;
}
});
// Load JS files second (functions) - can reference JSON data
jsFiles.forEach((file) => {
const functionName = file.replace(".js", "");
const filePath = join(globalDir, file);
try {
const code = readFileSync(filePath, "utf-8");
const script = new vm.Script(code, { filename: file });
// Execute in context with all VM globals and previously loaded variables
const tempContext = vm.createContext({
...globalVMContext,
...globalVariableContext,
});
const exportedObject = script.runInContext(tempContext);
globalVariableContext[functionName] = exportedObject;
logger.info(`Loaded global functions: ${functionName}`, {
file: file,
exports: Object.keys(exportedObject || {}).length,
});
} catch (error) {
logger.error(`Failed to load ${file}`, { error: error.message });
throw error;
}
});
logger.info(
`Loaded ${allFiles.length} global variables from ${globalDir}`,
{ json: jsonFiles.length, js: jsFiles.length }
);
} catch (error) {
logger.error("Failed to load global variables", {
directory: globalDir,
error: error.message,
});
throw error;
}
} }
/** /**
* Load configuration from config/default.json * Load configuration from config/default.json and merge with environment variables
* Merges with environment variables (ENV takes precedence)
*
* @returns {Object} Configuration object
*/ */
function loadConfig() { function loadConfig() {
const configPath = join(__dirname, "..", "config", "default.json"); const configPath = join(__dirname, "..", "config", "default.json");
const configData = readFileSync(configPath, "utf-8"); const configData = readFileSync(configPath, "utf-8");
const config = JSON.parse(configData); const config = JSON.parse(configData);
// Merge environment variables (ENV vars take precedence) // Merge environment variables (ENV takes precedence)
config.server.port = process.env.PORT return {
? parseInt(process.env.PORT, 10) ...config,
: config.server.port; server: {
config.server.host = process.env.HOST || config.server.host; ...config.server,
config.logging.level = process.env.LOG_LEVEL || config.logging.level; port: process.env.PORT ? parseInt(process.env.PORT, 10) : config.server.port,
host: process.env.HOST || config.server.host,
return config; },
logging: {
...config.logging,
level: process.env.LOG_LEVEL || config.logging.level,
},
};
} }
/** /**
* Validate configuration * Validate configuration
* @param {Object} config - Configuration object
* @throws {Error} If configuration is invalid
*/ */
function validateConfig(config) { function validateConfig(config) {
const errors = []; if (!config.server.port || config.server.port < 1 || config.server.port > 65535) {
throw new Error("Invalid server.port (must be 1-65535)");
// Validate server configuration
if (
!config.server.port ||
config.server.port < 1 ||
config.server.port > 65535
) {
errors.push("Invalid server.port (must be 1-65535)");
}
if (errors.length > 0) {
throw new Error(`Configuration validation failed:\n${errors.join("\n")}`);
} }
} }
@@ -177,8 +128,6 @@ async function startServer() {
// Create HTTP server that delegates all requests to proxy // Create HTTP server that delegates all requests to proxy
const server = http.createServer((req, res) => { const server = http.createServer((req, res) => {
try { try {
// Create a context with all globals that proxy.js needs
// globalVariableContext includes both JSON data and helpers object
const context = vm.createContext({ const context = vm.createContext({
...globalVMContext, ...globalVMContext,
...globalVariableContext, ...globalVariableContext,