From 67763a339d8b053f77a68d349ffb78a907b0faaa Mon Sep 17 00:00:00 2001 From: Jack Arturo Date: Thu, 24 Jul 2025 18:58:15 +0200 Subject: [PATCH 1/2] Fix file path resolution for config files Replaced usage of URL and import.meta.url.pathname with fileURLToPath for consistent file path resolution in Provider and promptLoader modules. This improves compatibility across environments and fixes issues with locating config files. --- src/providers/base/Provider.js | 5 ++++- src/utils/promptLoader.js | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/providers/base/Provider.js b/src/providers/base/Provider.js index 815bb71..a15b30b 100644 --- a/src/providers/base/Provider.js +++ b/src/providers/base/Provider.js @@ -1,4 +1,6 @@ import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; /** * Abstract Provider Base Class. @@ -41,7 +43,8 @@ export class Provider { */ async _loadProviderPricing(providerName) { try { - const pricingPath = new URL(`../../../config/${providerName}-pricing.json`, import.meta.url).pathname; + const currentDir = path.dirname(fileURLToPath(import.meta.url)); + const pricingPath = path.resolve(currentDir, '..', '..', '..', 'config', `${providerName}-pricing.json`); const pricingContent = fs.readFileSync(pricingPath, 'utf-8'); this.providerPricing = JSON.parse(pricingContent); diff --git a/src/utils/promptLoader.js b/src/utils/promptLoader.js index 8024704..b7a9989 100644 --- a/src/utils/promptLoader.js +++ b/src/utils/promptLoader.js @@ -8,6 +8,7 @@ import fs from 'fs'; import path from 'path'; +import { fileURLToPath } from 'url'; import { encoding_for_model as encodingForModel } from 'tiktoken'; import { getApiTargetLanguage } from './languageMapping.js'; import { getPluralForms, extractPluralCount } from './poFileUtils.js'; @@ -49,7 +50,7 @@ function loadPromptTemplate(promptFilePath) { */ export function buildSystemPrompt(targetLang, sourceLang = 'English', promptFilePath = null) { if (!promptFilePath) { - const currentDir = path.dirname(new URL(import.meta.url).pathname); + const currentDir = path.dirname(fileURLToPath(import.meta.url)); promptFilePath = path.resolve(currentDir, '../../config/prompt.md'); } From ec4c42adf5c519581728b761bf13142cea5d788e Mon Sep 17 00:00:00 2001 From: Vlad Date: Wed, 20 Aug 2025 12:19:27 -0400 Subject: [PATCH 2/2] Use fileURLToPath for cross-platform file paths --- src/providers/base/Provider.js | 3 ++- src/utils/costTracker.js | 3 ++- tools/ab-prompt-test | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/providers/base/Provider.js b/src/providers/base/Provider.js index a15b30b..06d5497 100644 --- a/src/providers/base/Provider.js +++ b/src/providers/base/Provider.js @@ -44,7 +44,8 @@ export class Provider { async _loadProviderPricing(providerName) { try { const currentDir = path.dirname(fileURLToPath(import.meta.url)); - const pricingPath = path.resolve(currentDir, '..', '..', '..', 'config', `${providerName}-pricing.json`); + const configDir = path.resolve(currentDir, '../../../config'); + const pricingPath = path.join(configDir, `${providerName}-pricing.json`); const pricingContent = fs.readFileSync(pricingPath, 'utf-8'); this.providerPricing = JSON.parse(pricingContent); diff --git a/src/utils/costTracker.js b/src/utils/costTracker.js index ad67891..678825b 100644 --- a/src/utils/costTracker.js +++ b/src/utils/costTracker.js @@ -1,5 +1,6 @@ import fs from 'fs'; import path from 'path'; +import { fileURLToPath } from 'url'; /** * Cost Tracking Utility. @@ -56,7 +57,7 @@ function loadProviderPricingData(providerName) { } try { - const currentDir = path.dirname(new URL(import.meta.url).pathname); + const currentDir = path.dirname(fileURLToPath(import.meta.url)); // Look for {provider}-pricing.json in the config directory relative to this module. const jsonPath = path.resolve(currentDir, `../../config/${providerName}-pricing.json`); diff --git a/tools/ab-prompt-test b/tools/ab-prompt-test index 0b14dc3..43bae94 100755 --- a/tools/ab-prompt-test +++ b/tools/ab-prompt-test @@ -5,6 +5,7 @@ import { OpenAI } from 'openai'; import chalk from 'chalk'; import fs from 'fs'; import path from 'path'; +import { fileURLToPath } from 'url'; import { getPromptTokenCount } from '../src/utils/promptLoader.js'; import { getLanguageName } from '../src/utils/languageMapping.js'; import { buildXmlPrompt, parseXmlResponse, buildDictionaryResponse } from '../src/utils/xmlTranslation.js'; @@ -156,7 +157,7 @@ let modelCosts; let fallbackPricing; try { - const currentDir = path.dirname(new URL(import.meta.url).pathname); + const currentDir = path.dirname(fileURLToPath(import.meta.url)); const configPath = path.resolve(currentDir, '../config/openai-pricing.json'); const costData = JSON.parse(fs.readFileSync(configPath, 'utf8')); @@ -280,7 +281,7 @@ async function testTranslation(openai, testStrings, promptConfig, targetLang) { }; // Load dictionary and find matches (like potomatic does). - const currentDir = path.dirname(new URL(import.meta.url).pathname); + const currentDir = path.dirname(fileURLToPath(import.meta.url)); const dictionaryDir = currentDir; // Look for dictionary files in tools directory. const dictionary = loadDictionary(dictionaryDir, targetLang, mockLogger); const dictionaryMatches = findDictionaryMatches(batch, dictionary);