{
  "version": 3,
  "sources": ["../../../src/plugins/create-require/plugin.ts"],
  "sourceRoot": "file://",
  "sourcesContent": ["/**\n * @file Plugins - create-require\n * @module mkbuild/plugins/create-require/plugin\n */\n\nimport { constant, define, join, regexp } from '@flex-development/tutils'\nimport {\n  transform,\n  type BuildOptions,\n  type BuildResult,\n  type OutputFile,\n  type Plugin,\n  type PluginBuild\n} from 'esbuild'\nimport util from 'node:util'\n\n/**\n * Plugin-specific build options.\n *\n * @internal\n */\ntype SpecificOptions = { metafile: true; write: false }\n\n/**\n * Returns a plugin that defines the `require` function in ESM bundles.\n *\n * When outputting ESM, any `require` calls will be replaced with esbuild's\n * `__require` shim, since [`require` is not defined in ESM environments][1].\n *\n * The shim first checks if `require` is polyfilled. If it is, the shim passes\n * the call to `require.apply`. If `require` isn't defined, an error will be\n * thrown: `Dynamic require of \"' + x + '\" is not supported`.\n *\n * This is particularly problematic when bundling, especially when targeting\n * node ([`platform === 'node'`][2]), since [built-in modules][3] are marked\n * as [`external`][4] by esbuild automatically. `require`ing these modules, as\n * well as other externals, will generate a runtime error. This is described\n * in [`evanw/esbuild#1921`][5].\n *\n * To circumvent this issue, output files containing the shim will have a\n * snippet insert that defines `require` using [`module.createRequire`][6].\n *\n * [1]: https://nodejs.org/api/esm.html#no-require-exports-or-moduleexports\n * [2]: https://esbuild.github.io/api/#platform\n * [3]: https://nodejs.org/api/esm.html#builtin-modules\n * [4]: https://esbuild.github.io/api/#external\n * [5]: https://github.com/evanw/esbuild/issues/1921\n * [6]: https://nodejs.org/api/module.html#modulecreaterequirefilename\n *\n * @return {Plugin} `create-require` plugin\n */\nconst plugin = (): Plugin => {\n  /**\n   * Inserts a `require` function definition into ESM bundles.\n   *\n   * [1]: https://esbuild.github.io/plugins\n   * [2]: https://esbuild.github.io/api/#build-api\n   *\n   * @param {PluginBuild} build - [esbuild plugin api][1]\n   * @param {BuildOptions} build.initialOptions - [esbuild build api][2] options\n   * @param {PluginBuild['onEnd']} build.onEnd - Build end callback\n   * @return {Promise<void>} Nothing when complete\n   */\n  const setup = async ({\n    initialOptions,\n    onEnd\n  }: PluginBuild): Promise<void> => {\n    const {\n      absWorkingDir = process.cwd(),\n      banner: { js: banner = '' } = {},\n      bundle,\n      format = 'esm',\n      metafile,\n      minify = false,\n      minifySyntax,\n      minifyWhitespace,\n      platform = 'node',\n      target = [],\n      write\n    } = initialOptions\n\n    // do nothing if bundling is not enabled\n    if (!bundle) return void bundle\n\n    // do nothing if not creating esm bundle\n    if (format !== 'esm') return void format\n\n    // esbuild write must be disabled to access result.outputFiles\n    if (write) throw new Error('write must be disabled')\n\n    // metafile required to get output metadata\n    if (!metafile) throw new Error('metafile required')\n\n    /**\n     * Code snippet that defines `require` using [`module.createRequire`][1].\n     *\n     * [1]: https://nodejs.org/api/module.html#modulecreaterequirefilename\n     *\n     * @const {string} snippet\n     */\n    const snippet: string = join(\n      [\n        'import { createRequire as __createRequire } from \\'node:module\\'',\n        'const require = __createRequire(import.meta.url)'\n      ],\n      '\\n'\n    )\n\n    // transform snippet to re-add banner and minify\n    let { code } = await transform(snippet, {\n      banner,\n      minifySyntax: minifySyntax ?? minify,\n      minifyWhitespace: minifyWhitespace ?? minify,\n      platform,\n      target\n    })\n\n    // remove new line from end of code snippet if output should be minified\n    if (minify || minifyWhitespace) code = code.replace(/\\n$/, '')\n\n    return void onEnd((result: BuildResult<SpecificOptions>): void => {\n      /**\n       * Regex used to deduce if an output file includes the `__require` shim.\n       *\n       * @const {RegExp} filter\n       */\n      const filter: RegExp = /Dynamic require of \".*\" is not supported/m\n\n      // insert require function definitions\n      result.outputFiles = result.outputFiles.map((output: OutputFile) => {\n        // do nothing if output file does not contain shim\n        if (!filter.test(output.text)) return output\n\n        // get hashbang\n        const [hashbang = ''] = /^#!.+\\n/.exec(output.text) ?? []\n\n        /**\n         * {@linkcode output.text} copy.\n         *\n         * @var {string} text\n         */\n        let text: string = output.text.replace(hashbang, '')\n\n        // remove banner\n        if (banner) text = text.replace(new RegExp(regexp(banner) + '\\n?'), '')\n\n        // redefine output text to insert require function definition\n        define(output, 'text', { get: constant(hashbang + code + text) })\n\n        // reset output file contents\n        output.contents = new util.TextEncoder().encode(output.text)\n\n        /**\n         * Relative path to output file.\n         *\n         * **Note**: Relative to {@linkcode absWorkingDir}.\n         *\n         * @const {string} outfile\n         */\n        const outfile: string = output.path\n          .replace(absWorkingDir, '')\n          .replace(/^\\//, '')\n\n        /**\n         * Output contents size including `require` function definition.\n         *\n         * @const {number} bytes\n         */\n        const bytes: number = Buffer.byteLength(output.contents)\n\n        // reset output file size\n        result.metafile.outputs[outfile]!.bytes = bytes\n\n        return output\n      })\n    })\n  }\n\n  return { name: 'create-require', setup }\n}\n\nexport { plugin as default }\n"],
  "mappings": ";;AAKA,SAAS,UAAU,QAAQ,MAAM,cAAc;AAC/C;AAAA,EACE;AAAA,OAMK;AACP,OAAO,UAAU;AAqCjB,MAAM,SAAS,8BA+HN,EAAE,MAAM,kBAAkB,OAnHnB,8BAAO;AAAA,EACnB;AAAA,EACA;AACF,MAAkC;AAChC,QAAM;AAAA,IACJ,gBAAgB,QAAQ,IAAI;AAAA,IAC5B,QAAQ,EAAE,IAAI,SAAS,GAAG,IAAI,CAAC;AAAA,IAC/B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,SAAS,CAAC;AAAA,IACV;AAAA,EACF,IAAI;AAMJ,MAHI,CAAC,UAGD,WAAW;AAAO;AAGtB,MAAI;AAAO,UAAM,IAAI,MAAM,wBAAwB;AAGnD,MAAI,CAAC;AAAU,UAAM,IAAI,MAAM,mBAAmB;AASlD,QAAM,UAAkB;AAAA,IACtB;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA;AAAA,EACF;AAGA,MAAI,EAAE,KAAK,IAAI,MAAM,UAAU,SAAS;AAAA,IACtC;AAAA,IACA,cAAc,gBAAgB;AAAA,IAC9B,kBAAkB,oBAAoB;AAAA,IACtC;AAAA,IACA;AAAA,EACF,CAAC;AAGD,UAAI,UAAU,sBAAkB,OAAO,KAAK,QAAQ,OAAO,EAAE,IAEtD,KAAK,MAAM,CAAC,WAA+C;AAMhE,UAAM,SAAiB;AAGvB,WAAO,cAAc,OAAO,YAAY,IAAI,CAAC,WAAuB;AAElE,UAAI,CAAC,OAAO,KAAK,OAAO,IAAI;AAAG,eAAO;AAGtC,YAAM,CAAC,WAAW,EAAE,IAAI,UAAU,KAAK,OAAO,IAAI,KAAK,CAAC;AAOxD,UAAI,OAAe,OAAO,KAAK,QAAQ,UAAU,EAAE;AAGnD,MAAI,WAAQ,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,MAAM,IAAI;AAAA,EAAK,GAAG,EAAE,IAGtE,OAAO,QAAQ,QAAQ,EAAE,KAAK,SAAS,WAAW,OAAO,IAAI,EAAE,CAAC,GAGhE,OAAO,WAAW,IAAI,KAAK,YAAY,EAAE,OAAO,OAAO,IAAI;AAS3D,YAAM,UAAkB,OAAO,KAC5B,QAAQ,eAAe,EAAE,EACzB,QAAQ,OAAO,EAAE,GAOd,QAAgB,OAAO,WAAW,OAAO,QAAQ;AAGvD,oBAAO,SAAS,QAAQ,OAAO,EAAG,QAAQ,OAEnC;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AACH,GAjHc,SAmHyB,IA/H1B;",
  "names": []
}
