{"version":3,"sources":["../../src/fixExtensionsPlugin.ts"],"sourcesContent":["import { type Plugin } from \"esbuild\";\n\n/**\n * ESBuild plugin that ensures all relative import paths in the output files\n * have the correct file extensions (.mjs or .cjs), appending them if missing.\n * This is useful for environments that require explicit file extensions in imports.\n *\n * @returns {import('esbuild').Plugin} An ESBuild plugin object.\n */\nexport const fixExtensionsPlugin = (): Plugin => ({\n  name: \"fixExtensionsPlugin\",\n  setup: (build) => {\n    // Determine if the output format is ESM (ECMAScript Module).\n    const isEsm = build.initialOptions.format === \"esm\";\n\n    // Determine the output file extension based on the build options.\n    const outExtension = build.initialOptions.outExtension?.[\".js\"] ?? \".js\";\n\n\n    // Hook into the 'onEnd' event of the build process.\n    build.onEnd((result) => {\n      // If there are build errors, do not proceed.\n      if (result.errors.length > 0)     return;\n      \n      // Iterate over each output file generated by ESBuild.\n      for (const outputFile of result.outputFiles ?? []) {\n\n\n        // Only target files with the specified output extension.\n        // This ignores additional files emitted, like sourcemaps (e.g., \"*.js.map\").\n        if (!outputFile.path.endsWith(outExtension)) {\n          continue;\n        }\n\n        // Get the original file contents.\n        const fileContents = outputFile.text;\n\n        // Modify the file contents by appending the correct file extensions.\n        const nextFileContents = modifyRelativeImports(\n          fileContents,\n          isEsm,\n          outExtension\n        );\n\n        // Update the output file contents with the modified contents.\n        outputFile.contents = Buffer.from(nextFileContents);\n      }\n    });\n  },\n});\n\n/**\n * Regular expression to match CommonJS require statements with relative paths.\n * Captures the import path and an optional semicolon.\n */\nconst CJS_RELATIVE_IMPORT_EXP = /require\\s*\\(\\s*[\"'](\\..+?)[\"']\\s*\\)(;?)/g;\n\n/**\n * Regular expression to match ESM import statements with relative paths.\n * Captures the import path and an optional semicolon.\n */\nconst ESM_RELATIVE_IMPORT_EXP = /from\\s*([\"'])(\\.[^\"']+)\\1([^;]*;?)/g;\n\n/**\n * Regular expression to detect if the import path already contains an explicit .js extension\n */\nconst hasJSExtensionRegex = /\\.(?:js)$/i;\n\n/**\n * Regular expression to detect if the import path already has an extension (that is not .js),\n * such as .png, .svg, .jpeg, .jpg, etc.\n */\nconst hasNonJSExtensionRegex =\n  /\\.(?:png|svg|css|scss|csv|tsv|xml|toml|ini|jpe?g|json|md|mdx|json|yaml|gif|webp|ico|mp4|webm|ogg|wav|mp3|m4a|aac|webm|woff2?|eot|ttf|otf|wasm)$/i;\n\n/**\n * Modifies the contents of a file by appending the correct file extensions\n * to relative import paths, depending on the module format.\n *\n * @param {string} contents - The contents of the file to modify.\n * @param {boolean} isEsm - Indicates whether the module format is ESM.\n * @returns {string} The modified file contents.\n */\nconst modifyRelativeImports = (\n  contents: string,\n  isEsm: boolean,\n  outExtension: string\n) =>\n  isEsm\n    ? modifyEsmImports(contents, outExtension)\n    : modifyCjsImports(contents, outExtension);\n\n/**\n * Modifies ESM import statements in the file contents by ensuring that\n * all relative import paths have the correct .mjs extension appended.\n *\n * @param {string} contents - The contents of the file to modify.\n * @returns {string} The modified file contents with updated import paths.\n */\nconst modifyEsmImports = (contents: string, outExtension: string) => {\n\n  return contents.replace(\n    ESM_RELATIVE_IMPORT_EXP,\n    (_, quote, importPath, rest = \"\") => {\n\n      // If the import path ends with '.' or '/', it likely refers to a directory.\n      if (importPath.endsWith(\".\") || importPath.endsWith(\"/\")) {\n        // Append '/index.mjs' to the path.\n        return `from ${quote}${importPath}/index${outExtension}${quote}${rest}`;\n      }\n\n      // If the import path already ends with '.mjs', leave it as is.\n      if (importPath.endsWith(outExtension)) {\n        return `from ${quote}${importPath}${quote}${rest}`;\n      }\n\n      // If the import path has an explicit .js extension and the out extension is different, replace the existing extension.\n      if (hasJSExtensionRegex.test(importPath) && outExtension !== \".js\") {\n        const updatedImportPath = importPath.replace(\n          hasJSExtensionRegex,\n          outExtension\n        );\n        return `from ${quote}${updatedImportPath}${quote}${rest}`;\n      }\n\n      // If the import path has an existing extension (e.g., .png, .svg), leave it as is.\n      if (hasNonJSExtensionRegex.test(importPath)) {\n        return `from ${quote}${importPath}${quote}${rest}`;\n      }\n\n      // Otherwise, append '.mjs' to the import path.\n      return `from ${quote}${importPath}${outExtension}${quote}${rest}`;\n    }\n  );\n};\n\n/**\n * Modifies CommonJS require statements in the file contents by ensuring that\n * all relative import paths have the correct .cjs extension appended.\n *\n * @param {string} contents - The contents of the file to modify.\n * @returns {string} The modified file contents with updated require paths.\n */\nconst modifyCjsImports = (contents: string, outExtension: string) => {\n  return contents.replace(\n    CJS_RELATIVE_IMPORT_EXP,\n    (_, importPath, maybeSemicolon = \"\") => {\n      // If the import path ends with '.' or '/', it likely refers to a directory.\n      if (importPath.endsWith(\".\") || importPath.endsWith(\"/\")) {\n        // Append '/index.cjs' to the path.\n        return `require('${importPath}/index${outExtension}')${maybeSemicolon}`;\n      }\n\n      // If the import path has an explicit .js extension and the out extension is different, replace the existing extension.\n      if (hasJSExtensionRegex.test(importPath) && outExtension !== \".js\") {\n        const updatedImportPath = importPath.replace(\n          hasJSExtensionRegex,\n          outExtension\n        );\n        return `require('${updatedImportPath}')${maybeSemicolon}`;\n      }\n\n      // If the import path already ends with '.cjs', leave it as is.\n      if (importPath.endsWith(outExtension)) {\n        return `require('${importPath}')${maybeSemicolon}`;\n      }\n\n      // If the import path has an existing extension (e.g., .png, .svg), leave it as is.\n      if (hasNonJSExtensionRegex.test(importPath)) {\n        return `require('${importPath}')${maybeSemicolon}`;\n      }\n\n      // Otherwise, append '.cjs' to the import path.\n      return `require('${importPath}${outExtension}')${maybeSemicolon}`;\n    }\n  );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASO,MAAM,sBAAsB,OAAe;AAAA,EAChD,MAAM;AAAA,EACN,OAAO,CAAC,UAAU;AAEhB,UAAM,QAAQ,MAAM,eAAe,WAAW;AAG9C,UAAM,eAAe,MAAM,eAAe,eAAe,KAAK,KAAK;AAInE,UAAM,MAAM,CAAC,WAAW;AAEtB,UAAI,OAAO,OAAO,SAAS,EAAO;AAGlC,iBAAW,cAAc,OAAO,eAAe,CAAC,GAAG;AAKjD,YAAI,CAAC,WAAW,KAAK,SAAS,YAAY,GAAG;AAC3C;AAAA,QACF;AAGA,cAAM,eAAe,WAAW;AAGhC,cAAM,mBAAmB;AAAA,UACvB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAGA,mBAAW,WAAW,OAAO,KAAK,gBAAgB;AAAA,MACpD;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAMA,MAAM,0BAA0B;AAMhC,MAAM,0BAA0B;AAKhC,MAAM,sBAAsB;AAM5B,MAAM,yBACJ;AAUF,MAAM,wBAAwB,CAC5B,UACA,OACA,iBAEA,QACI,iBAAiB,UAAU,YAAY,IACvC,iBAAiB,UAAU,YAAY;AAS7C,MAAM,mBAAmB,CAAC,UAAkB,iBAAyB;AAEnE,SAAO,SAAS;AAAA,IACd;AAAA,IACA,CAAC,GAAG,OAAO,YAAY,OAAO,OAAO;AAGnC,UAAI,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,GAAG,GAAG;AAExD,eAAO,QAAQ,KAAK,GAAG,UAAU,SAAS,YAAY,GAAG,KAAK,GAAG,IAAI;AAAA,MACvE;AAGA,UAAI,WAAW,SAAS,YAAY,GAAG;AACrC,eAAO,QAAQ,KAAK,GAAG,UAAU,GAAG,KAAK,GAAG,IAAI;AAAA,MAClD;AAGA,UAAI,oBAAoB,KAAK,UAAU,KAAK,iBAAiB,OAAO;AAClE,cAAM,oBAAoB,WAAW;AAAA,UACnC;AAAA,UACA;AAAA,QACF;AACA,eAAO,QAAQ,KAAK,GAAG,iBAAiB,GAAG,KAAK,GAAG,IAAI;AAAA,MACzD;AAGA,UAAI,uBAAuB,KAAK,UAAU,GAAG;AAC3C,eAAO,QAAQ,KAAK,GAAG,UAAU,GAAG,KAAK,GAAG,IAAI;AAAA,MAClD;AAGA,aAAO,QAAQ,KAAK,GAAG,UAAU,GAAG,YAAY,GAAG,KAAK,GAAG,IAAI;AAAA,IACjE;AAAA,EACF;AACF;AASA,MAAM,mBAAmB,CAAC,UAAkB,iBAAyB;AACnE,SAAO,SAAS;AAAA,IACd;AAAA,IACA,CAAC,GAAG,YAAY,iBAAiB,OAAO;AAEtC,UAAI,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,GAAG,GAAG;AAExD,eAAO,YAAY,UAAU,SAAS,YAAY,KAAK,cAAc;AAAA,MACvE;AAGA,UAAI,oBAAoB,KAAK,UAAU,KAAK,iBAAiB,OAAO;AAClE,cAAM,oBAAoB,WAAW;AAAA,UACnC;AAAA,UACA;AAAA,QACF;AACA,eAAO,YAAY,iBAAiB,KAAK,cAAc;AAAA,MACzD;AAGA,UAAI,WAAW,SAAS,YAAY,GAAG;AACrC,eAAO,YAAY,UAAU,KAAK,cAAc;AAAA,MAClD;AAGA,UAAI,uBAAuB,KAAK,UAAU,GAAG;AAC3C,eAAO,YAAY,UAAU,KAAK,cAAc;AAAA,MAClD;AAGA,aAAO,YAAY,UAAU,GAAG,YAAY,KAAK,cAAc;AAAA,IACjE;AAAA,EACF;AACF;","names":[]}